I am having issues with a project I am working on. There is a main loop that runs the program which calls the update()
method every frame.
I have an object that is a World
which contains a HashMap<ChunkPos, Chunk>
where a ChunkPos
is a data structure that has an xyz position which represents a Chunk
's position in the World
I am attempting to iterate through all the Chunks in my the world in my update function, as each Chunk has it's own ArrayList of GameObject
that has all of the objects inside this chunk of the world.
public void update() {
HashMap<ChunkPos, Chunk> chunkMap = world.getChunkMap();
Iterator<Map.Entry<ChunkPos, Chunk>> it = chunkMap.entrySet().iterator();
while(it.hasNext()) {
Map.Entry<ChunkPos, Chunk> item = it.next();
ArrayList<GameObject> chunkObjects = item.getValue().getObjects();
for(GameObject obj : chunkObjects) {
obj.update();
}
}
}
However, when I run the program, I am receiving a ConcurrentModificationException
at this line:
Map.Entry<ChunkPos, Chunk> item = it.next();
I've tried multiple different ways of iterating through the HashMap, but each time I end up with this same error. What am I doing wrong?
Here is the full StackTrace if it helps:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$EntryIterator.next(HashMap.java:1463)
at java.util.HashMap$EntryIterator.next(HashMap.java:1461)
at com.anzanama.lwjgl3d.Game.Game.update(Game.java:40)
at com.anzanama.lwjgl3d.Game.Game.loop(Game.java:31)
at com.anzanama.lwjgl3d.Main.main(Main.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Just wanted to make a note here: I eventually ended up implementing a WorldChangeScheduler that would schedule changes to be made to the world once it has iterated through the whole world and updated it. This makes it more robust and has the added benefit that I can later go back and turn these WorldChanges into events that other people using my engine can hook into.