删除ArrayList中的重复元素,并在第一个元素后面的括号中添加总出现次数

时间:2012-03-22 10:31:33

标签: java arraylist duplicates

初学者。我有一个String ArrayList,在打印时基本上看起来像这样(但是根据用户输入改变值):

[22,37,77,77,98,101,104,107,107,107,150]

我想删除重复的元素,并在第一个元素后面的括号中添加出现的总数,所以它看起来像这样:

[22,37,77(2),98,101,104,107(3),150]

我已经想出了如何删除重复元素,但我无法弄清楚其余部分。

到目前为止,这是我的代码(ArrayList称为重复):

int q, z;
for(q = 0; q < duplicates.size() - 1; q++) {  
    for(z = q + 1; z < duplicates.size() - 1; z++) {
        if(duplicates.get(q).equals(duplicates.get(z))) {
            duplicates.remove(q);
        }
    }
}

System.out.println(duplicates);

结果输出为:

[22,37,77,98,101,104,107,150]

是否有人建议我如何获得那些出现次数的括号?我一直在努力想出一种方法来计算每个值删除的重复项,但我所能计算的是重复项删除期间的总数,这不是特别有用。

ArrayList最初是一个Integer ArrayList,但我把它改成了String ArrayList,所以我可以在元素中添加非数字字符。

8 个答案:

答案 0 :(得分:2)

我建议使用 Map 。您可以使用它将密钥与有用的值相关联。在这种情况下,键将是要处理的数组的元素,值将是数组中每个元素的出现次数。你的伪代码是:

initialize a map of appropriate size and type
iterate the array to be processed. for each element in array:

set key:= current element in array
set value := value from map corresponding to key
if value is null, initialize value to 1
store value for key in map

然后在结束时,您将迭代地图的键并打印出键及其对应的值。

答案 1 :(得分:1)

  

ArrayList最初是一个Integer ArrayList,但我把它改成了String ArrayList,所以我可以在元素中添加非数字字符。

这是一个错误。不要混淆您希望如何在代码中存储数据以及如何将其显示给用户。如果您将值存储为List String,那么您自己就会变得更难。将值存储在最容易编码的格式中,并且只有在想要显示它们时才转换为字符串。

所以你想要的是每个这些的唯一数字和计数列表。 Map是理想的,因为它将一个键 - 在你的因果中映射整数 - 映射到一个值 - 计数。

所以你需要循环你的数字,然后在Map中计算它们。在下面的代码中,我假设listList<Integer>

Map<Integer,Integer> counts = new HashMap<Integer,Integer>();

for (int number : list) {
  int count = counts.containsKey(number) ? counts.get(number) : 0;
  count += 1;
  counts.put(number,count);
}

然后,您可以通过循环Map.keySet()Map.entrySet()来构建输出,

答案 2 :(得分:0)

首先,我建议你将列表保留为整数列表。不要使用System.out.println(duplicates),而是自己做一个循环。无论如何,这真的很容易。


计算出现次数:

我建议您保留Map<Integer, Integer>,将数字映射到出现次数。这可以在第一遍中初始化,如下所示:

  1. 对于列表中的每个元素 i for (int i : duplicates)
    1. 如果 i 不在地图中(map.containsKey(i)
      1. 添加映射 i - &gt; 0(map.put(i, 0)
    2. 增加键 i map.put(i, map.get(i) + 1)
    3. 的值

  2. 使用出现次数打印列表:

    您打印列表如下:

    1. 为已打印的数字
    2. 创建HashSet<Integer> printed
    3. 列表中的每个元素 i
      1. 如果printed,请继续:(if (printed.contains(i)) continue;
      2. 打印 i
      3. 如果映射的值> gt; 1为 i ,在括号中打印数字
      4. i 添加到打印件中。 (printed.add(i)

    4. 完成练习循环后,只需执行

      即可删除重复项
      list = new ArrayList<Integer>(new LinkedHashSet<Integer>(list));
      

答案 3 :(得分:0)

声明ArrayList<Integer>进行计数:

ArrayList<Integer> counts = new ArrayList<Integer>();

然后当您删除副本时,请计算

            duplicates.remove(q);
            counts.set(q, counts.get(q) + 1);

答案 4 :(得分:0)

LinkedHashMap对你来说足够好了。 Map接口的哈希表和链表实现,具有可预测的迭代顺序。因此,我建议使用LinkedHashMap,如下所示:

    public static LinkedHashMap<String,Integer> removeDuplicate(List<String> list)
{
    LinkedHashMap<String,Integer> map = new LinkedHashMap<String,Integer>();
    for(String str:list)
    {
        Integer count = map.get(str);
        if(count == null)
        {
            map.put(str, 1);
        }else{
            map.put(str, ++count);
        }
    }
    return map;
}

public static void main(String[] args)
{
    List<String> list = new ArrayList<String>();
    list.add("123");
    list.add("45");
    list.add("678");
    list.add("123");
    System.out.println(removeDuplicate(list));
}

答案 5 :(得分:0)

在(IMHO非常有用)谷歌图书馆Guava的帮助下,你可以写下这个:

List<String> duplicate = ImmutableList.of("22", "37", "77", "77", "98", "101", "104", "107", "107", "107", "150");

System.out.println(duplicate); 

Multiset<String> withoutDuplicate = LinkedHashMultiset.create();
withoutDuplicate.addAll(duplicate);

System.out.println(withoutDuplicate); 

这会产生

[22, 37, 77, 77, 98, 101, 104, 107, 107, 107, 150]
[22, 37, 77 x 2, 98, 101, 104, 107 x 3, 150]

这不完全是你的格式,但为此它是一个双线。

答案 6 :(得分:0)

List<Integer> completeList = new ArrayList<Integer>();
completeList.add(22);
completeList.add(22);
completeList.add(37);
completeList.add(77);
completeList.add(77);
completeList.add(98);
completeList.add(101);
completeList.add(107);
completeList.add(107);
completeList.add(107);
completeList.add(150);

System.out.println(completeList);

// Using a sortedSet to remove the duplicates
SortedSet<Integer> nonDupSet = new TreeSet<Integer>(completeList);
System.out.println(nonDupSet);

List<String> datawithParan = new ArrayList<String>();
//Looping through the completeList with the nonDup List and counting the dups.
// and then populating a List with the required Format
for (Integer nonDup: nonDupSet) {
    int count = 0;
    for (Integer complete: completeList) {                      
      if(nonDup == complete) {
        count++;
      }
    }

    datawithParan.add(nonDup +"(" + count + ")");
}
System.out.println(datawithParan);

答案 7 :(得分:-1)

以下是您的完整代码:

public static void main(String[] args) {
    /* Make list */
    List<String> input = new ArrayList<String>();
    input.add("12");
    input.add("11");
    input.add("11");
    input.add("12");
    input.add("12");
    input.add("15");
    input.add("12");
    input.add("17");
    input.add("18");
    input.add("11");

    /*
     * count duplicates
     */
    Map<String, Integer> map = new LinkedHashMap<String, Integer>();
    for (String str : input) {
        if (map.containsKey(str)) {
            Integer prevCount = map.get(str);
            map.put(str, ++prevCount);
        } else {
            map.put(str, 0);
        }
    }

    /*
     * make string to display
     */
    StringBuffer sb = new StringBuffer();
    for (Map.Entry<String, Integer> entry : map.entrySet()) {

        String key = entry.getKey();
        Integer count = entry.getValue();
        if (count == 0) {
            sb.append(key + ", ");
        } else
            sb.append(key + "(" + count + "), ");
    }
    String tmp = sb.toString();
    String output = tmp.substring(0, tmp.length() - 2); //remove last ", "
    System.out.println("[" + output + "]");

}