2014-09-02 49 views
1

我有一個球員列表。 此列表包含沒有目標的玩家。目標意味着一名玩家瞄準另一名玩家,他們兩人是目標,並且不應該在名單中。Java ConcurrentModificationException當刪除兩個索引,當前和隨機一個

以下循環的目的是遍歷所有玩家並搜索目標,如果玩家尚未準備好,它只會調用tick()方法,該方法基本上會勾選目標搜索計時器。 isReady方法基本上是timer == 0

for (Client c : participants) { 
     PlayerTargetDomain dom = c.getTarget(); 
     if (dom.isReady()) { 
      if (dom.getSearchDelay() == 0) { 
       SharedTargetDomain d; 
       if ((d = search(c)) != null) { 
        participants.removeAll(Arrays.asList(d.getFirst(), d.getSecond())); 
        continue; 
       } 
      } 
      else { 
       dom.tickSearchDelay(); 
      } 
     } 
     else dom.tick(); 
    } 

現在search()方法,基本上是尋找一個匹配的目標,如果發現它會建立SharedTargetDomain包含當前索引,找到目標索引對象。

如果從search(Client)返回SharedTargetDomain實例是不是空的,我會使用removeAll()

不幸的是,participants列表中刪除這兩個對象,如果我刪除任何人我會收到以下錯誤:

java.util.ConcurrentModificationException 
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source) 
    at java.util.ArrayList$Itr.next(Unknown Source) 
    at mod.game.TargetManager.execute(TargetManager.java:24) 

線24是這樣的:

for (Client c : participants) { 

爲什麼我收到THI S'我已經嘗試過使用Iterator作爲當前索引,但是我仍然得到錯誤,因爲我也刪除了其他索引,但是如果刪除它,另一個與當前索引有什麼關係?我真的誤解了一些東西。

謝謝!

Iterator實現:

Iterator<Client> itr = participants.iterator(); 
    while(itr.hasNext()) { 
     Client c = itr.next(); 
     if (c != null) { 
      PlayerTargetDomain dom = c.getTarget(); 
      if (dom.isReady()) { 
       if (dom.getSearchDelay() == 0) { 
        SharedTargetDomain d; 
        if ((d = search(c)) != null) { 
         participants.remove(d.getSecond()); 
         itr.remove(); 
         continue; 
        } 
       } 
       else { 
        dom.tickSearchDelay(); 
       } 
      } 
      else dom.tick(); 
     } 
    } 
+0

哪裏是你的代碼,你有'Iterator'試過嗎? '迭代器'工作正常,在迭代時刪除元素。 – Braj 2014-09-02 15:42:36

+0

它不是當前索引有問題,當您修改其他某個正在使用的列表時,會發生ConcurrentModificationException。你能告訴我們你使用迭代器的實現嗎? – 2014-09-02 15:45:11

+0

@JonTaylor添加了Iterator實現,錯誤顯示在itr.remove()行。 – Artemkller545 2014-09-02 15:47:11

回答

3

問題是你修改集合在迭代它。

有至少兩個解決方案

  1. 使用索引訪問。處理索引會帶來很多樂趣,因爲元素在移除後會被移位。
  2. 收集您需要在完成迭代後刪除並應用所有更改的元素,您總會記住您處理的元素可能已經計劃刪除,您將獲得很多樂趣。
+0

與第二個選項。 – Braj 2014-09-02 15:50:09

+1

可以使用的CopyOnWriteArrayList也 – 2014-09-02 15:50:23

+0

有趣的答案:d:d – 2014-09-02 15:53:34

0

您可以使用

的CopyOnWriteArrayList避免此異常