【问题标题】:remove duplicates in LinkedList删除 LinkedList 中的重复项
【发布时间】:2015-09-08 15:58:15
【问题描述】:

我是java初学者。我编写了以下代码来查找重复项并在 LinkedList 中删除它们,但我得到了 ArrayIndexOutOfBounds 异常。请帮忙。提前致谢。

    import java.util.*;
    public class LinkedListEx 
{
    public static void main(String[] args)
    {
        LinkedList<Integer> l1 = new LinkedList<Integer>();
        l1.add(1);
        l1.add(2);
        l1.add(1);
        l1.add(4);
        l1.add(1);
        System.out.println(l1);
        int i = l1.size();
        for(int j=0;j<i;j++)
        {
            for(int k=j+1;k<i;k++)
            {
                if(l1.get(j) == l1.get(k)){
                    l1.remove(k);
                }
            }
        }
    }
 }

【问题讨论】:

  • 问题是 int k=j+1 在第二个循环中检查是否对列表有效然后进入该循环。
  • 你能使用其他数据结构吗?
  • @StackFlowed - 不 - 它的 j&lt;i - 应该是 j&lt;i-1

标签: java collections linked-list


【解决方案1】:

不要在LinkedList 上使用get(int)ArrayList 上没问题,但 LinkedList 必须遍历列表才能找到第 n 个元素。

使用Set 记住哪些值已被查看,并使用Iterator 迭代列表。

LinkedList<Integer> l1 = new LinkedList<Integer>();
l1.add(1);
l1.add(2);
l1.add(1);
l1.add(4);
l1.add(1);
System.out.println(l1);

HashSet<Integer> set = new HashSet<Integer>();
for (Iterator<Integer> iter = l1.iterator(); iter.hasNext(); ) {
    Integer value = iter.next();
    if (! set.add(value))
        iter.remove();
}
System.out.println(l1);

输出

[1, 2, 1, 4, 1]
[1, 2, 4]

【讨论】:

  • 这段代码太棒了......我花了一些时间才明白 set 不需要重复......这个网站教会了我很多 :-)
  • 如果我将 LinkedList 转换为集合会发生什么?是否会自动删除重复项??
  • @pavan 是的。这就是 Puce 的答案所依赖的。他只需将列表中的所有元素添加到保留顺序的集合 (LinkedHashSet),然后将(现在不同的)值复制回列表。请注意,HashSet 也可以使用,但不会保留原始顺序,TreeSet 实际上会对值进行排序。
【解决方案2】:

当你要修改列表时,使用迭代器遍历列表。

您正在从列表中删除项目,这会减小列表的大小,但您的循环仍会针对列表的初始大小运行。

【讨论】:

  • 非常感谢。我没有意识到这一点。
  • 那么没有其他方法可以使用 for 循环吗?
  • 你可以的。你在做。但这不是正确的方法。
  • 使用迭代器也可以使用 for 循环。像 - for (Iterator&lt;Integer&gt; iterator = yourList.iterator(); iterator.hasNext();) { Integer item = iterator.next(); .... }
【解决方案3】:

试试:

List<Integer> list = new LinkedList<>();
...

Set<Integer> set = new LinkedHashSet<>(list);
// either
list = new LinkedList<>(set);

// or
list.clear();
list.addAll(set);

使用 Java SE 8,您还可以使用:

list = list.stream().distinct().collect(Collectors.toCollection(LinkedList::new));

或者如果它不必是 LinkedList(根据我的经验并不经常需要):

list = list.stream().distinct().collect(Collectors.toList());

【讨论】:

  • 简洁明了,但它不会从原始列表中删除重复项,它会替换列表。根据实际需要,您的答案可能是完美的,也可能是无用的。 ;-)
  • @Andreas 如果您更喜欢原始列表对象,您可以使用 clear() 和 addAll() ...
  • @Andreas 谢谢,已修复。
  • @Puce 这是在不使用任何逻辑的情况下删除重复项的简洁且最简单的方法。谢谢:-)
【解决方案4】:

您的for loop 应该更像这样并且还通过更新您的变量i

int i = l1.size();
for(int j=0;j<i-1;j++) {
       for(int k=j+1;k<i;k++) {
           if(l1.get(j) == l1.get(k)) {
               l1.remove(k);
               i--; //Updated size
           }
       }
}

【讨论】:

  • 抱歉,这不起作用我遇到了同样的异常
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 2022-01-20
  • 1970-01-01
  • 2012-01-01
相关资源
最近更新 更多