繁体   English   中英

删除重复链表并发修改异常

[英]removing duplicates linkedlist concurrent modification exception

我有一个链表,其中每个元素都有键和值( ArrayList<dataStructure> )。 我想合并具有相同键的元素。

    Iterator<CElem> oItr = linkedList.iterator();
    {
        while (oItr.hasNext())
        {
            CElem outer = oItr.next();              
            Iterator<CElem> iItr = linkedList.iterator();
            {
                while (iItr.hasNext())
                {
                    CElem inner = iItr.next();
                    if (outer.equals(inner))
                        continue;

                    if (outer.getKey().equals(inner.getKey()))
                    {
                        outer.getValues().addAll(inner.getValues());
                        iItr.remove();
                    }
                }
            }
        }
    }

虽然我正在使用迭代器,但删除了一个java.util.ConcurrentModificationException 什么应该改变摆脱这一点。

使用其中一个迭代器删除元素,因此第二个不知道此删除并抛出ConcurrentModificationException

BTW:

你应该考虑使用一些多图来代替具有键值对的列表

两个迭代器都遍历链表

Iterator<CElem> oItr = linkedList.iterator();
....
Iterator<CElem> iItr = linkedList.iterator();

可能iItr应该是内部数组列表?

更新上面的答案我误解了这个问题。 但挑战是你有两个遍历列表的迭代器,所以当你使用一个迭代器的remove()方法时,另一个仍然会检测到并发修改。

通常,要从列表中删除重复项,您可以通过Set(例如HashSet)运行它们,但这对您不起作用,因为它只是密钥重复,而不是列表的整个成员。

我采取的方法是尝试在单独的列表中查找并捕获重复的密钥及其值,然后合并并删除重复项作为单独的步骤。

在另一个List中添加要删除的元素,然后在末尾循环该列表以删除这些元素。

或者,使用地图/集。

问题是,当你使用iItr.remove()它会修改列表, iItr很满意,因为它知道改变了什么,但是oItr不是。 我可以看到有三种可能的解决方案:

  1. 切换到并发列表(例如ConcurrentLinkedQueue - 但请参阅Java中的无锁并发链接列表中的答案以获取有关此问题的警告)
  2. 切换到一个集合结构,例如TreeSet ,它将自动保持您的项目唯一(但不会保留其顺序)
  3. 从其中一个中删除之后,请确保不使用其他迭代器 - 您可以通过切换要删除的元素来执行此操作, iItr.remove()更改为:

      oItr.remove(); break; 

这将导致删除每个键的第一个实例,而不是后续的,这可能不是您想要的行为 - 在这种情况下,您可以尝试向后迭代列表。

这会有用吗?

 Iterator<CElem> oItr = linkedList.iterator();
    {
        while (oItr.hasNext())
        {
            CElem outer = oItr.next();              
            Iterator<CElem> iItr = linkedList.iterator();
            {
                while (iItr.hasNext())
                {
                    CElem inner = iItr.next();
                    if (outer.equals(inner))
                        continue;

                    if (outer.getKey().equals(inner.getKey()))
                    {
                        inner.getValues().addAll(outer.getValues());
                        outer.remove();
                        break;
                    }
                }
            }
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM