在循环中合并冗余信息

时间:2014-03-17 19:25:41

标签: java arrays arraylist

在Java中,我有一个数组,其中包含一系列有时冗余的键值对,我想将它们整合到一个只有唯一键的较短的arraylist中。如何编辑以下代码来完成此操作?

以下是outputarr数组中的数据示例:

key value
448 Ethanol
448 Alcohol
448 Alcohol
448 Ethanol
448 Ethanol
448 Alcohol
448 Ethanol
448 Alcohol
448 Ethyl alcohol  

我想将上述内容合并到一个包含以下数据的数组中:

key value
448 Ethanol; Alcohol; Ethyl alcohol

因此,数组中的9行合并为arraylist中的一行。 arraylist中的值是串联字符串"Ethanol; Alcohol; Ethyl alcohol"。但是,每个数字键都将具有不同数量的值,这些值需要以这种方式连接,以便生成单个值字符串,列出与数组中的数字键关联的唯一名称。

这是我到目前为止的代码,如何编辑它以使其完成我所描述的内容?

private static ArrayList<ArrayList<String>> twoDimArrList = new ArrayList<ArrayList<String>>();
public void someMethod(){
    int len = 1000;
    String[][] outputarr = new String[len][2];
    // ommitting code that populates outputarr because the next for loop is what needs help

    for(int r=0;r<len;r++){
        ArrayList<String> temp = new ArrayList<String>();
        if(outputarr[r][0]==outputarr[r+1][0]){
            if(outputarr[r][1].equalsIgnoreCase(outputarr[r+1][1])){
                temp.add(outputarr[r][0]);
                temp.add(outputarr[r][1]);
                twoDimArrList.add(temp);
                r+=1;
            }
        }
    }
}  

1 个答案:

答案 0 :(得分:0)

有很多方法可以做到这一点。一种方法是使用Map<Integer,Set<String>>来保存数据,这会将键映射到值集。

然后,当您阅读数据时:

Map<Integer,Set<String>> data = new HashMap<Integer,Set<String>>();

for each item in the file {

    Integer key = ...; // parsed 
    String value = ...; // parsed

    // retrieve set if it exists, create if it doesn't.
    Set<String> values = data.get(key);
    if (values == null) { 
        values = new HashSet<String>();
        data.put(key, values);
    }

    // add value to set
    values.add(value);

}

如果要存储重复值,请使用List代替Set。如果你想要,例如计算值,考虑创建一个包含值及其计数的新类(适当实现equals()hashCode()和/或Comparable),并存储Set您读取值时更新的那些。

您可以设想其他任何方法,但最终所有方法都归结为如上所述:将整数ID映射到值集合。

如果您使用third-party multimaps之一,基本上实现了上述代码,例如Guava或Apache Commons实现,您也可以稍微简化一下代码。不幸的是,JDK没有任何内置的多图(see "Multimaps" section here)。


迭代容器中的值时,

HashMapHashSet不保证任何特定顺序。如果您有特定的订购要求,TreeMap / TreeSet将按升序(Comparable / Comparator定义的自然顺序)和LinkedHashMap进行迭代/ LinkedHashSet将保留添加元素的顺序。上面的容器可以根据需要替换它们。

对于迭代数据,可以使用标准方法和语法,例如:

for (Map.Entry<Integer,Set<String>> entry : data.entrySet()) {
    Integer key = entry.getKey();
    // ...
    for (String value : entry.getValue()) {
       // ...
    }
}

您在当前输出格式化尝试中犯的错误是依靠Set默认toString()实现来生成输出。默认的toString()无法真正猜测您的具体要求,您需要迭代数据并生成满足您要求的输出。