ConcurrentModificationException error when removing item from ArrayList?

65 views Asked by At

I am a beginner at Java and game programming. I am working on a Java 2D game and adding an inventory and looting system. Basically, when my player picks up an item, I want to remove the physical object from the world. However, I am getting a ConcurrentModificationException error. Here is a part of my code (which I think may be part of the problem so I will include the code):

for (GameObject obj : goManager.gameObjects) {
    if (obj instanceof ItemObject itemObj) {
        if (bounds().intersects(itemObj.getBounds())) {
            collidingItem = itemObj;
        } else {
            collidingItem = null;
        }
    }
}

And this is the code where the error happens:

inventory.add(collidingItem.getItem());
goManager.gameObjects.remove(collidingItem); // Error happens here
collidingItem = null;

The output:

Exception in thread "Thread-0" java.util.ConcurrentModificationException
    at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
    at com.yiwuen.PixelBlock.entity.GameObjectManager.render(GameObjectManager.java:12)
    at com.yiwuen.PixelBlock.Game.render(Game.java:146)
    at com.yiwuen.PixelBlock.Game.run(Game.java:103)
    at java.base/java.lang.Thread.run(Thread.java:833)

I'm not sure how to remove the colliding item from the ArrayList because when I do so, that error occurs. Any thoughts?

I've also tried to just set the colliding item to null but that obviously didn't work. I researched but I didn't understand any of the solutions.

2

There are 2 answers

0
hermit On

If you are trying to remove an element from the list inside the loop, do it using an Iterator.

for (Iterator<GameObject> it = goManager.gameObjects.iterator(); it.hasNext(); ) {
    GameObject obj = it.next();
    // method logic 

    // remove using Iterator.
    it.remove()
}
2
ash On

In java ,there has a counter-intuitive method ,is that we can not delete item from list by iterator. If the object named gameObjects defined by you ,i suggest you convert the data type to CopyOnWriteArrayList If not ,you could use the following code

public static void main(String[] args) {
        ArrayList<String> strings = new ArrayList<>();
        strings.add("a");
        strings.add("b");
        strings.add("c");
        strings.add("d");
        strings.add("e");

        for (int i = 0; i < strings.size(); i++) {
            if("c".equalsIgnoreCase(strings.get(i))){
                strings.remove(i);
                // important 
                i--;
            }
        }

        System.out.println("strings = " + strings);

    }

Above are a simple instance,you could believe this is a good practice.