I am iterating over a List of CustomObject and while doing this iteration, I am mutating this object by adding a tag to tags list of this custom object. I am not adding or removing any CustomObject to or from customObjects (List). I am still getting java.util.ConcurrentModifcationException.
public class CustomObject {
private List<Tag> tags;
// Getter for Tag
// Setter for tag
}
public class DummyClass {
List<CustomObject> addMissingTag(List<CustomObject> customObjects) {
for (CustomObject object:customObjects) { // line 5
// following method adds a tag to tags list of CustomObject
mutateObjectByAddingField(object); // line 7
// Some Code
}
return customObjects;
}
void mutateObjectByAddingField(CustomObject customObject) {//line 13
Boolean found = false;
for (Tag tag:customObject.getTags()) { // line 15
if ("DummyKey".equalsIgnoreCase(tag.getKey())) {
found = true;
break;
}
}
if (!found) {
Tag tag = new Tag("DummyKey", "false");
List<Tag> tags = customObject.getTags();
tags.add(tag);
customObject.setTags(tags);
}
}
}
Here is the stack trace:
java.util.ConcurrentModificationException: null
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) ~[?:1.8.0_131]
at java.util.ArrayList$Itr.next(ArrayList.java:851) ~[?:1.8.0_131]
at DummyClass.mutateObjectByAddingField(DummyClass.java:15)
at DummyClass.addMissingTag(DummyClass.java:7)
Does this mean we can get ConcurrentModifcationException even if we just try to modify the object and not remove or add from/to the list/collection?
First, you are using a
List
type in thefor
loop to iterate the elements, so the enhanced for statement is equivalent to a for using an iterator, as mentioned here, becauseList
implementsIterator
. Also, it's obvious from the stack trace.When using
Iterator
, you can't make modifications on the list you are iterating, as mentioned GeeksForGeeks, you will getConcurrentModificationException
.So, to solve this issue, you can for example implement explicitly the for loop using integers like below: