for循环增强遍历ArrayList时删除元素:ConcurrentModificationException
java.util.ConcurrentModificationException
- jdk源码中指出
此异常可能由检测到并发的方法引发,在不允许修改对象时修改了该对象
编译器在看到一个实现了Interator接口的对象,当该对象在使用增强for循环时,
会自动重写,变成使用迭代器来遍历集合。
如果一个线程发出一系列违反对象契约的方法调用,该对象可能会抛出此异常。
增强for循环遍历ArrayList集合将指定元素放到集合后面报错
- 增强for循环的特点
1、增强for使用增强for循环的时候不能使用集合删除集合中的元素;
2、增强for循环不能使用迭代器中的方法,例如remove()方法删除元素;
3、与普通for循环的区别:增强For循环有遍历对象,普通for循环没有遍历对象; - 代码如下
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//使用增强for循环将集合中为c的元素放在集合最后面
for (String str:list) {
if (str.equals("c")){
String string = str;
list.remove(str);
list.add(string);
}
}
因为编译器在看到一个实现了Interator接口的对象,当该集合对象在使用增强for循环时,会自动地重写,变成使用迭代器来遍历集合。
所以如上代码相当于如下代码
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String string = iterator.next();
if (string.equals("c")){
list.remove(string);
list.add(string);
}
}
- 运行结果
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:886)
at java.util.ArrayList$Itr.next(ArrayList.java:836)
at Test.main(Test.java:28)
普通for循环将元素放到集合的后面
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
System.out.println("修改前" + list);
for(int i = 0;i<list.size();i++){
if(list.get(i).equals("c"){
String str = list.get(i);
list.remove(i);
list.add(str);
}
System.out.println("修改后" + list);
}
- 运行结果
修改前[a, b, c, d]
修改后[a, b, d, c]
增强for循环解决方案
- 使用并发容器CopyOnWriteArrayList
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
System.out.println("修改前" + list);
for (String str:list) {
if (str.equals("c")){
String string = str;
list.remove(str);
list.add(string);
}
}
System.out.println("修改后" + list);
- 运行结果
修改前[a, b, c, d]
修改后[a, b, d, c]
原文地址
https://blog.csdn.net/qq_20492999/article/details/81216453