Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
at TestDeleteList.main(TestDeleteList.java:21)
的异常.
为什么会出现这个异常?。如果
删除的不是
”bbb”,
而是
”ddd”,
(倒数第二个)则不会产生异常。
2:对集合进行删除,不会出现异常
List<String> list =new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
list.add("fff");
list.add("ggg");
for(int i=0;i<list.size();i++){
String str = list.get(i);
if(str.equals("eee")){
list.remove(str);
}
}
}
不会发生异常的原因是,这里没有涉及迭代器,也没有对集合是否发生改变进行判断,所以不会发生异常!
3:使用迭代器删除,不会抛出异常
for(Iterator<String> it=list.iterator();it.hasNext();){
String str=it.next();
if("bbb".equals(str)){
it.remove();//使用迭代器删除,不会抛出异常
}
}
使用迭代器进行删除,一切正常。查看迭代器的源代码(AbstractList 类中的Itr内部类)中的remove方法:
lastRet在Itr内部类中定义,表示最后操作的元素的索引号,每次迭代器的next方法执行之后,lastRet的值都会加1,但是一旦迭代器执行了remove方法之后,lastRet被重新赋值为-1,expectedModCount与modCount被更新成相等。所以迭代器在执行next方法的时候,调用checkForComodfification()进行检查的时候,不会抛出异常。
总结
对集合进行删除的时候,是否抛出ConcurrentModificationException异常,与使用哪个remove方法有关系。如果使用的是集合对象的remove方法,modCount的值就会改变,此时通过迭代器的next方法获取元素,就会进行检查,此时就会抛出异常。如果使用的是迭代器的remove方法,则不会改变modCount的值,通过迭代器next方法元素的时候,不会抛出异常。 所以对于在对集合进行迭代的时候删除其中的元素,最好使用迭代器的remove方法进行删除