2011-11-06 66 views
0

我得到一些問題,讓這項工作以及我的方面:Java的ArrayList的併發修改

for(Iterator<Object> i = mylist.iterator(); i.hasNext();) { 
     Object obj = i.next(); 
     ArrayList<Object> newlist = new ArrayList<Object>(); 
     newlist.add(obj); 
     i.remove(); 
     for(Iterator<Object> in = mylist.iterator(); in.hasNext();) { 
      Object next = in.next(); 
      if (obj != next && (another condition)) { 
       newlist.add(next); 
       in.remove(); 
      } 
     } 
     if (newlist.size() > 2) anotheList.add(newlist); 
     else for(Object r : newlist) { 
      //mylist get back object: 
      mylist.add(r); 
     } 
    } 

我試圖得到一個優雅的方式來做到這一點,而不復制MYLIST越來越多的時間.. 。

+2

你能解釋一下你正在做什麼,以及爲什麼這段代碼沒有做你想做的事情? – unholysampler

+5

這看起來很糟糕...你想做什麼?我無法確定,但似乎你正試圖從現有列表中的一些元素中創建一個新列表,但這似乎是一個可怕的方式來做到這一點。你能更詳細地描述你想完成什麼嗎? – Lucas

+0

我知道,我已經簡化了我的代碼,讓它更具可讀性......我需要做的是從一個大列表中做出一些列表,只保留丟棄的對象。其他完成先決條件的列表將分隔存儲在另一個對象中。同時大列表已採取新對象來檢查此功能 – Achilleterzo

回答

6

目前什麼代碼正在做的是:

  • 在外環的第一次迭代:
    • 刪除第一個元素。
    • 在第1內部循環,去除不「==」的第一個元素(我們只是刪除)
    • 如果我們去掉大於2組的元素所有其他元素,把它們放在別的地方。
    • 否則將元素放回到列表的末尾。

顯然,這種跑入在外環的第二次迭代併發修改,因爲內循環修改了你的外循環遍歷集合。你不能那樣做。

但是,更重要的是,該算法沒有多大意義。在我看來,這很可能意味着代碼沒有做你打算做的事情。除非你解釋你實際上試圖通過來實現,否則我們無法弄清真正的問題是什麼,以及如何解決它。


我還是不明白究竟你想達到什麼樣的,但我認爲該解決方案將涉及以下的一種或兩種:

  • 更改實現類的myList到並行收集類別確實允許併發修改;例如ConcurrentLinkedDeque

  • 與此更換外循環:

    while (!myList.isEmpty()) { 
        Object obj = myList.remove(0); 
        ... 
    } 
    

後者補救擺脫的ConcurrentModificationException前提是什麼,而第1內部循環運行否則修改的列表。第一種補救措施完全擺脫了ConcurrentModificationException,除了不能保證第一個內部循環會看到添加到別處的元素。

在任何一種情況下,如果在處理條目時沒有進度,則必須擔心如何終止循環。

「大O」的複雜性也是一個問題,但不可能不理解「其他條件」在做什麼。

+0

就像一個紙牌遊戲,新的列表是玩遊戲,其他人是手中的牌,但我意識到這不能與另一部分代碼一起工作,那麼我需要返回到我的舊代碼,而不需要從除非我玩這個遊戲。 – Achilleterzo

+0

我不能使用一段時間,因爲「mylist」不會變空 – Achilleterzo

+0

@Achilleterzo - 這就是我的意思是由第二句到最後一句。有辦法解決這個問題;例如通過將標記對象放入列表中。 –