#Avoiding ConcurrentModification Exception
1 messages · Page 1 of 1 (latest)
<@&987246399047479336> please have a look, thanks.
Here is an AI assisted attempt to answer your question 🤖. Maybe it helps! In any case, a human is on the way 👍. To continue talking to the AI, you can use </chatgpt:1108714622413963314>.
le, a GameObject is added or removed from the set while it is being iterated through. This can lead to a ConcurrentModificationException being thrown.
To avoid this exception, you can use an Iterator to iterate through the set instead of directly using a for-each loop. By using an Iterator, you can safely add or remove elements from the set during iteration without causing any issues.
Here's an example of how you can iterate through your set using an Iterator:
Set<GameObject> gameObjects = new HashSet<>();
Iterator<GameObject> iterator = gameObjects.iterator();
while (iterator.hasNext()) {
GameObject gameObject = iterator.next();
gameObject.update();
// Add or remove objects safely
if (/* some condition */) {
iterator.remove(); // Remove current object
}
if (/* some other condition */) {
gameObjects.add(new GameObject()); // Add new object
}
}
By using an Iterator and its remove() method, you can avoid the ConcurrentModificationException and safely modify your set while iterating through it. Additionally, make sure to synchronize access to your set if it is being modified by multiple threads to prevent any concurrency issues.
whats the error? concurrent mod?
or index out of bounds?
conccurent
sounds like youre using an enhanced for loop
for(GameObject obj : objs) {
}```
yeah?
no i am using an iterator
remove the element using the iterator
the problem is that i am not removing the object in the loop exactly
i can't , the removing happens in a completely different class further down the line
Scene#update is called each game loop, the function loops through all the stored objects and updates them
I have a PlayerEntity which extends GameObject, the player clicks on a block and it needs to be removed from the scene's list
so you are using an iterator to iterate through the collection. but then trying to remove from the collection directly?
yes i think
concurrentmod occurs when you try to remove while iterating
yeah, dont do that
theres a reason it fails
its referred to as a "fail-fast" iterator
its failing because it knows the operation you are doing is dangerous & can lead to bugs
so its failing before those bugs can occur
The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException
(from the docs of ArrayList, although applies to other lists)
the iterator's remove function doesn't take any input tho, how do i specify which object i need to remove
Should i then iterate over the complete set again?
you can only remove the current element using an iterator
there are hackish tricks you can do to get rid of the error, but at the cost of potential bugs
the problem is that the operation you're trying to perform isnt safe
if you remove from a collection directly, thats going to impact any iterators that currently exist
so you cant remove while the list is being iterated, unless you remove the current element, through the iterator
you gotta rethink your structure
basically, if you're iterating over a collection, you shouldnt be removing elements before or after
I am not sure how to do that
shouldn't this be a common problem for games?
its a common problem in lots of environments
the solution is proper design. you're suggesting the "remove" code is nested, existing in other classes
your list shouldnt be that accessible
instead, the class that owns the list should provide ways to communicate changes, and the class that needs to remove something should communicate that with the class that owns the list
that way these kinds of situations are kept under control, by a single class
encapsulate the list
I am doing that, i think
the Scene class contains the list of objects, I call Scene.removeObject(object) .
The problem is, that object won't be the current element of the iterator
for example, the iterator is currently on the PlayerEntity, but the player tries to break a grass block, I have to remove the grass block from the list
maybe I could solve it for now by updating the player separately
flag it for removal on the next update cycle
but it would cause issues later if i wanna do something more fancy
oh, I could try that
wow thank you that worked!!
I add the objects i need to remove into another set, and then contains check in the iterator and remove it
since ArrayList is index-based, its iterator is also index based. by removing elements ahead of the current, you risk out of bounds type errors, NoEuchElementException
if you remove before the current element, the list will shift all the elements, once again messing up the indexing
so yeah, cant be doing that
glad you got it fixed up
you can, or itll auto-close after a while
btw, heres the implementation for the iterator of ArrayList
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/ArrayList.java#L1036-L1098
if you wanted to do some investigation
