我有这种代码的和平。
我知道这必须给我ConcurrentModificationException
我必须使用迭代器或克隆列表或只是使用for循环。
问题是这段代码运行没有问题,ls.remove可以在0-2之间的任何索引上运行
现在如果我将 s.equals(“两个”)更改为 s.equals(“one”)或列表中除“两个”之外的任何其他内容“
我将始终按预期获得ConcurrentModificationException。
另外,如果我取消注释ls.add(“4”)行,无论 s.equals()是什么,我都会有ConcurrentModificationException。
并且我的问题是为什么会发生这种情况以及为什么下面的代码只对s.equals(“two”)运行良好而没有ConcurrentModificationException?
import java.util.*;
import java.util.List;
public class Test {
public static void main(String args[]) {
List<String> ls = new ArrayList<>();
ls.add("one");
ls.add("two");
ls.add("three");
//ls.add("four");
for(String s : ls) {
if(s.equals("two")) {
ls.remove(0);
//ls.remove("three");
}
}
System.out.println(ls.size());
}
}
和输出
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at Test.main(Test.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:140)
答案 0 :(得分:1)
迭代时不得修改列表。迭代器可能(或可能不)失败,具体取决于实现。因此,删除部分列表中的某些元素可能有效,有些则可能无效。解决此问题的保存方法是使用迭代器remove方法,或使用CopyOnWriteArrayList或支持此类修改的任何其他集合。