ConcurrentModificationException异常处理
问题引入:
通常在对集合进行更新操作,会出现一个java.util.ConcurrentModificationException
;该异常的出现往往在对集合遍历操作时,从集合中删除或者新增元素导致
ArrayList<String> c = new ArrayList<>();
c.add("james");
c.add("kobe");
c.add("curry");
for (String s:c) {
//next()
if(Objects.equals("curry",s)){
c.add("aaa");
//c.remove(s);
}
}
运行以上程序会出现如下异常:
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 com.softeem.j2106.collection.TestArrayList.main(TestArrayList.java:20)
导致以上问题出现的原因:
在对集合迭代过程中,修改了集合的结构,导致并发修改异常。
该异常产生的原理:
- 在ArrayList中所有的更新方法都有对其中
modCount
字段进行修改(modCount
表示的是集合结构被修改的次数)
- 在获取迭代器对象(
Iterator
)时,内部会将modCount
值传递给迭代器的成员变量expectedModCount
,在使用迭代器对元素进行迭代操作时,每次都会检查预期的修次数值是否和实际的值一致,若不一致,则说明在迭代的同时,外部有对集合进行更新,此时迭代器会抛出一个异常ConcurrentModificationException
结论:
不要在对集合迭代时删除集合中的元素,或者向集合中新增元素
解决方案:
-
直接使用迭代器自身的remove方法:
Iterator<String> it = c.iterator(); while(it.hasNext()){ String s = it.next(); if(Objects.equals(s,"curry")){ //迭代器自身的删除 it.remove(); } }
-
在迭代时先记录元素对象,迭代完成之后再删除
String temp = null; for (String s:c) { if(Objects.equals("curry",s)){ temp = s; break; } } if(temp != null){ c.remove(temp); }
-
可以不使用迭代器,直接使用普通循环删除(只针对有序集合)
for (int i = 0; i < list.size(); i++) { String s = list.get(i); if(Objects.equals(s,"30")){ list.remove(s); } }