This question already has an answer here:
I have the following code below
Map<String, Integer> buyingItemEnumerationMap = this.toBuyItemEnumeration;
for (Entry<String, Integer> item : buyingItemEnumerationMap.entrySet()) {
if(RandomEngine.boolChance(50)){ //will delete?
buyingItemEnumerationMap.remove(item.getKey());
}
if(buyingItemEnumerationMap.size() == 1){
break;
}
}
now I am working with an android game and the code above is running in multithreaded way. Now I am having an exception which is java.util.ConcurrentModificationException
. I already researched on how I can solve the problem but seems not to work on me.
What I am doing on the code above is to remove an entry randomly. How can I implement it there?
Yes
you can't delete entries in a Map while traversing it by it's own property
. different approch.You cannot remove an element from a collection while iterating it unless you use an
Iterator
.This is what's causing the exception.
Use Iterator#remove() to remove an element while iterating over your collection like
EDIT : (in response to OP's comment)
Yes, the deletions done through
Iterator#remove()
over theSet
returned by HashMap.entrySet() would reflect in the underlyingMap
as theSet
is backed by it. Quoting the JavaDoc here:Use iterator in the forEach loop and use iterator.remove();
Use
Iterator
.HOW IT WORKS ?
The javadoc for
ConcurrentModificationException
says:If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.
The field
int expectedModCount
is initiated to be equal to the fieldprotected transient int modCount = 0;
(and this is valid for Collections and Maps), andmodCount
keeps track of the structural modifications over the object. IfmodCount
at some point of the iteration gets unequal toexpectedModCount
, then aConcurrentModificationException
is thrown.With using
Iterator
to make structural changes over the map/collection (like removing elements), we make sure that the removal operation will be executed properly, e.g. themodCount
will be equal to theexpectedModCount
.