【问题标题】:Remove every duplicated element from ArrayList从 ArrayList 中删除每个重复的元素
【发布时间】:2014-09-19 20:03:02
【问题描述】:

请在投票之前 - 阅读问题并检查示例 - 这不是重复的!

我想从 Java 中的 ArrayList 中删除 每个 重复的元素,如下所示:

Original list: [4, 2, 2, 3, 4, 1]
Set result: [1, 2, 3, 4]
Desired result: [1, 3]

重复的明显解决方案 - 设置在这里不起作用。

我的解决方案:

        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        arrayList.add(5);
        arrayList.add(1);
        arrayList.add(5);
        arrayList.add(1);
        arrayList.add(5);
        arrayList.add(2);
        arrayList.add(3);

        ArrayList<Integer> temp = new ArrayList<>(arrayList);

        for(Integer number : new HashSet<Integer>(arrayList)){
            temp.remove(number);
        }

        arrayList.removeAll(temp);

任何更聪明/更聪明的解决方案?

【问题讨论】:

  • 提供的副本不正确,但您仍然没有表现出任何努力。
  • 复制什么?无论如何,您面临的问题和问题是什么?我可以看到您想要实现的目标,但我看不到您解释阻止您实现目标的部分。
  • 我在 2 分钟前问过这个问题,并且因为重复的问题得到了 6 次反对票,但显然不是。
  • @mickey 您的链接不正确。选中“期望结果”,而不是“设置结果”。
  • 既然您已经有了一个可行的解决方案并且您有兴趣改进它(我认为它没有错误),您应该在codereview.stackexchange.com 上发布您的问题。一般规则是 (1) 如果您的代码有效,但如果您试图让您的代码在 Stack Overflow 上工作,您很想知道它如何在 Code Review 上更好地工作 (2)。无论如何,既然您已经在 Stack Overflow 上发布了您的问题,此建议是针对您未来的问题(您应该只在 StackExchange 网站之一上发布问题,因此选择 SO 或 CR,切勿在两个网站上发布相同的问题)。

标签: java arraylist duplicates duplicate-removal


【解决方案1】:

有很多方法可以做你想做的事。这是一个(其中 T 是您现有列表存储的类型):

  1. 分配一个Map&lt;T, Integer&gt;。该整数将用于存储该项目在您的列表中出现的次数。
  2. 遍历您的列表。查找地图中的每个项目。如果它不存在,则放回一个计数。如果它已经存在于地图中,增加计数并放回新的计数。
  3. 遍历地图中的条目以提取您的去重列表。您不会包含任何值大于 1 的条目。

即使对于大型列表,这种方法也会很快。

【讨论】:

  • 不错。我什至不需要计数器。简单的真/假就足够了:)
【解决方案2】:

您可以使用循环检查 ArrayList 中的重复项,然后在 ArrayList 上使用 remove() 删除元素。

请看以下内容:

{
    ArrayList list;
    // ...
    while(true)
        for(final Integer o : list) {
            if(list.indexOf(o) != list.lastIndexOf(o)) {
                while(list.remove(o));
                continue;
            }
            break;
        }
}

Alternatively 更好的方法是使用临时的Set 来存储要删除的对象:

{
    ArrayList list;
    TreeSet<Integer> set = new TreeSet<>(); // Use your Set!
    // ...
    for(final Integer o : list)
        if(list.indexOf(o) != list.lastIndexOf(o))
            set.add(o);
    for(final Integer o : set)
        while(list.remove(o));
}

【讨论】:

  • 我认为最好简单地复制列表 - 迭代一个并从另一个删除:)
  • 你不应该修改你正在使用 for-each 循环迭代的集合。
  • @Pshemo 我已经修好了。请注意,for中使用的Iterable-each循环同时调用.next()直到.hasNext()返回false,因此每次修改后需要重新开始迭代(continue->重做while(true)块->@ 987654332@-再次)。
  • 仅供参考,添加了使用临时 Set 的解决方案。
【解决方案3】:

或者,您也可以检查频率以及删除。 Collections.frequency(arrayList, number)

public static void main(String[] args) {
    ArrayList<Integer> arrayList = new ArrayList<Integer>();
    arrayList.add(5);
    arrayList.add(1);
    arrayList.add(5);
    arrayList.add(1);
    arrayList.add(5);
    arrayList.add(2);
    arrayList.add(3);

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

    for (Integer number : arrayList) {
        if (Collections.frequency(arrayList, number) == 1) {
            unique.add(number);
        }
    }

    System.out.println(unique);
}

【讨论】:

  • 您也可以将频率条件更改为 == 1,然后将结果列表用作那些不重复的数字的列表。
  • 是的。好主意。这将使额外的循环无效。更新了我的答案.. :)
猜你喜欢
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多