2013-05-16 124 views
0

我在併發修改異常時遇到問題。我已經改變了我的代碼來使用迭代器,但是當我刪除一個對象時,我仍然遇到了這些問題。出現我的錯誤就行了併發修改異常與對象

theEnemy = (Enemy) EnemyItr.next();

我不知道我將如何解決這個問題,因爲它是代碼的非常重要的一部分。

for (Iterator EnemyItr = activeEnemies.iterator(); EnemyItr.hasNext();){ 

    theEnemy = (Enemy) EnemyItr.next(); 
    try { 

     try { 

      if (theEnemy.x < 0 && theEnemy.y >= 5) { 
       activeEnemies.remove(theEnemy); 
      } 
     } catch (Exception e) { 
      System.err.println("Cannot Remove Enemy"); 
     } 

     Enemy.pathFind(Enemy.getXBlockOfEnemy(theEnemy.x), Enemy.getXBlockOfEnemy(theEnemy.y), theEnemy.x, theEnemy.y); 

     if (Enemy.right) { 
      theEnemy.x += Enemy.speed; 
      //System.out.println("right"); 
      //System.out.println(theEnemy.x + " " + theEnemy.y); 
     } else if (Enemy.down) { 
      theEnemy.y += Enemy.speed; 
      //System.out.println("down"); 
      //System.out.println(theEnemy.x + " " + theEnemy.y);; 
     } else if (Enemy.up) { 
      theEnemy.y -= Enemy.speed; 
      //System.out.println("up"); 
      //System.out.println(theEnemy.x + " " + theEnemy.y); 
     } else if (Enemy.left) { 
      theEnemy.x -= Enemy.speed; 
      //System.out.println("left"); 
      //System.out.println(theEnemy.x + " " + theEnemy.y); 
     } else { 
      System.out.println("Enemy Lost."); 
      //System.out.println(theEnemy.x + " " + theEnemy.y); 
     } 

     g.drawImage(enemy, theEnemy.x, theEnemy.y, this); 
     //System.out.println(Enemy.getXBlockOfEnemy(theEnemy.x)); 

     //drawing health bar 
     if (Input.displayUI) { 
      g.setColor(Color.LIGHT_GRAY); 
      g.fillRect(theEnemy.x, theEnemy.y - 10, 70, 10); 
      g.setColor(Color.RED); 
      g.fillRect(theEnemy.x + 2, theEnemy.y - 10 + 1, 68, 8); 
      g.setColor(Color.GREEN); 
      g.fillRect(theEnemy.x + 2, theEnemy.y - 10 + 1, (int) (.68 * theEnemy.enemylife), 8); 
     } 

    } catch (ConcurrentModificationException e) { 
     theEnemy = null; 
    } 

} 
+0

描述的例外是不言自明:你不能修改的集合,通過它你迭代。當你從列表中移除敵人時你會這麼做。 (並且不要僅僅捕獲這樣的異常;他們告訴你你的代碼有問題,你需要修復。) – dlev

+0

@dlev是的,我明白,但我不知道如何解決它,我不能刪除設置下一個對象的代碼。 –

+0

在這種情況下,您需要使用不同的機制來迭代您的集合。或者,創建集合的副本,對其進行迭代,然後從原始列表中刪除該對象。 – dlev

回答

3

在迭代迭代時從集合中移除元素的唯一機會是使用迭代器本身的remove()方法。但是由於這是一個可選方法,如果你的迭代器不支持remove方法,你可能不得不使用其他答案的建議。

簡而言之:使用迭代器的remove方法而不是集合本身的remove方法。

+0

+1。看到我的答案,而不使用迭代器的替代方法。 – user949300

+0

哇,多數民衆贊成在輝煌! 非常感謝@ mschenk74 –

1

問題是您迭代的集合在迭代時不支持修改。

ConcurrentModificationException

這是一個共同的需要從集合中篩選出「壞」的條目。通常情況下,我會這樣做:

public void filter(Collection<MyObject> myObjectsToFilter) { 
    final Collection<MyObject> toRemove = new HashSet<MyObject>(); 
    for(MyObject myObject : myObjectsToFilter) { 
     if(myObject.specificCondition()) { 
      toRemove.add(myObject); 
     } 
    } 
    myObjectsToFilter.removeAll(toRemove); 
} 

本示例保留要移除的對象的單獨集合。它是在迭代發生時建立的,迭代完成後,它將刪除所有條目。

1

一個典型的解決方案是創建要刪除的所有項目的列表,例如removeList。不要在你的循環中立即移除敵人,而應將其添加到removeList。在循環結束時,請致電activeEnemies.removeAll(removeList);

這種方式的一個優點是您無需打擾迭代器,只需循環訪問原始集合即可。

如果你選擇使用一個迭代器,使用它的去除方法,如@ mschenk74