0

I'm trying to remove an entity when isActive is false. When the entity attribute isActive is set to false, it enters if statement and removes the entity, when iterating through the entities list again after that and then crashes. From what I've researched I am using the correct way to remove an object from an array list.

the code when removing the entity and iterating through the list is

    for (Entity entity : entities) {// itaarate through all the entities in list of entities

        entity.render(shader, camera, this);// render each entity

        if (!entity.isActive())// checks if entity attribute is active
            entities.remove(entity);// removes entity from list

    }

when using the debugger after it removes the entity from the list, it goes back to the top of the for loop and then displays this page

enter image description here

the Variables window when debugging

enter image description here

the full error that displays in the console is

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at project.World.render(World.java:196)
at project.Main.<init>(Main.java:152)
at project.Main.main(Main.java:167)

the list being created is

public static ArrayList<Entity> entities; // contains all entities
GreyWolf18
  • 141
  • 1
  • 3
  • 13
  • 4
    Does this answer your question? [Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop](https://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re) – OH GOD SPIDERS Mar 24 '20 at 13:15

3 Answers3

3

java.util.ConcurrentModificationException displaying when using the correct remove() method

Actually, you are using the wrong method. Or more precisely the remove() method on the wrong object.

You can remove an element while iterating ... but you need to use the remove() method on the Iterator object; see the javadoc for more details.

Iterator<Entity> it = entities.iterator();
while (it.hasNext()) {
    Entity entity = it.next();
    entity.render(shader, camera, this);

    if (!entity.isActive()) {
        it.remove();
    }
}

Note that Iterator.remove() is an optional operation, but ArrayList iterators do implement it.

The ListIterator API has the same method, but Iterator is more general. (You can use the above sample code with any type that you can iterate with an Iterator, not just List types.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
2

You can't change a collection while iterating.

List<Entity> entitiesToRemove = new ArrayList<>();

for (Entity entity : entities) {
    entity.render(shader, camera, this);

    if (!entity.isActive()) {
        entitiesToRemove.add(entity);
    }
}

entities.removeAll(entitiesToRemove);
Smutje
  • 17,733
  • 4
  • 24
  • 41
0

From official java list tutorial:

for (ListIterator<E> it = list.listIterator(); it.hasNext();) {
    if (val == null ? it.next() == null : val.equals(it.next())) {
        it.remove();
    }
}

Adapting the example to your code:

for (ListIterator<Entity> it = entities.listIterator(); it.hasNext();) {
    Entity entity = it.next();
    entity.render(shader, camera, this);    
    if (entity.isActive()) {
        it.remove();
    }
}
dariosicily
  • 4,239
  • 2
  • 11
  • 17