我遇到并发修改异常的问题。我已经更改了我的代码以使用迭代器,但是当我删除对象时,我仍然遇到这些问题。我的错误发生在
行 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 :(得分:3)
在迭代过程中从集合中删除元素的唯一机会是使用迭代器本身的remove()方法。但是,由于这是一个可选方法,如果您的迭代器不支持remove方法,您可能必须使用其他答案中的建议。
简而言之:使用迭代器的remove方法而不是集合本身的remove方法。
答案 1 :(得分: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);
}
此示例保留要删除的单独对象集合。它是在迭代发生时构建的,迭代完成后会删除所有条目。
答案 2 :(得分:1)
典型的解决方案是创建要删除的所有项目的列表,例如removeList
。不要在循环过程中立即删除敌人,而是将其添加到removeList
。在循环结束时,请致电activeEnemies.removeAll(removeList);
这种方式的一个优点是你不需要打扰迭代器,你可以循环遍历原始集合。
如果您确实选择使用迭代器,请使用它的remove方法,如@ mschenk74所述