簡體   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