英文:
java.util.ConcurrentModificationException while mutating an object
问题
我正在对 CustomObject 的 List 进行迭代,而在此迭代过程中,我通过向此自定义对象的标签列表添加标签来改变此对象。我没有将任何 CustomObject 添加或移除到 customObjects(List<CustomObject>)中。但我仍然遇到 java.util.ConcurrentModificationException。
以下是代码部分:
public class CustomObject {
private List<Tag> tags;
// Tag 的 Getter 方法
// Tag 的 Setter 方法
}
public class DummyClass {
List<CustomObject> addMissingTag(List<CustomObject> customObjects) {
for (CustomObject object : customObjects) { // 第 5 行
// 下面的方法将一个标签添加到 CustomObject 的标签列表中
mutateObjectByAddingField(object); // 第 7 行
// 一些代码
}
return customObjects;
}
void mutateObjectByAddingField(CustomObject customObject) { // 第 13 行
Boolean found = false;
for (Tag tag : customObject.getTags()) { // 第 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);
}
}
}
以下是堆栈跟踪:
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)
这是否意味着即使我们只尝试修改对象而不是从列表/集合中删除或添加,我们仍然可能会遇到 ConcurrentModificationException?
英文:
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<CustomeObject>). 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?
答案1
得分: 1
首先,在for
循环中您正在使用List
类型来迭代元素,因此增强型的for语句相当于使用迭代器的for循环,正如此处所提到的,因为List
实现了Iterator
接口。从堆栈跟踪中也可以明显看出。
当使用Iterator
时,您不能在正在迭代的列表上进行修改,正如GeeksForGeeks中所述,否则将会抛出ConcurrentModificationException
。
因此,为了解决这个问题,您可以例如显式地使用整数来实现for
循环,如下所示:
for (int i = 0; i < customObjects.length(); i++) {
CustomObject object = customObjects.get(i);
// 下面的方法将向CustomObject的标签列表添加一个标签
mutateObjectByAddingField(object);
// 一些代码
}
英文:
First, you are using a List
type in the for
loop to iterate the elements, so the enhanced for statement is equivalent to a for using an iterator, as mentioned here, because List
implements Iterator
. 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 get ConcurrentModificationException
.
So, to solve this issue, you can for example implement explicitly the for loop using integers like below:
for (int i=0;i < customObjects.length(); i++) {
CustomObject object = customObjects.get(i);
// following method adds a tag to tags list of CustomObject
mutateObjectByAddingField(object);
// Some Code
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论