Reputation: 99
I am having trouble with a Concurrent modification exception. I have changed my code to use iterators however I am still getting these issues when I remove an object. My error occurs on the line
theEnemy = (Enemy) EnemyItr.next();
I'm not sure how I would get around this as it is a very important part of the code.
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;
}
}
Upvotes: 0
Views: 117
Reputation: 15729
A typical solution is to create a List, say, removeList
, of all the items to be removed. Instead of immediately removing the Enemy during your loop, add it to removeList
. At the end of your loop, call activeEnemies.removeAll(removeList);
An advantage of this way is that you don't need to bother with iterators, you can just loop over the original collection.
If you do choose to use an iterator, use it's remove method, as described by @mschenk74
Upvotes: 1
Reputation: 3591
The only chance to remove an element from a collection while iterating over it is to use the remove() method of the iterator itself. But since this is an optional method you may have to use the suggestions from the other answers here if your iterator doesn't support the remove method.
In short: use the remove method of the iterator instead of the remove method of the collection itself.
Upvotes: 3
Reputation: 42849
The issue is that the collection that you are iterating does not support modification while being iterated.
ConcurrentModificationException
It is a common need to filter out 'bad' entries from a collection. Typically, I would do it in this way:
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);
}
This example keeps a separate collection of objects to remove. It is built up while the iteration is happening, and after iteration is complete, it removes all of the entries.
Upvotes: 1