标签:
测试代码为:
public static void main(String[] args) {
List<String> strList = new ArrayList<String>();
strList.add("1");
strList.add("2");
strList.add("3");
strList.add("4");
for(String str:strList){
if(str.equals("4")){
strList.remove(str);
}
}
}
运行后结果如下:

跟踪代码,抛出异常的地方具体在:
public E next() {
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
遍历时返回一个元素之前,会调用checkForComodification()函数进行检查,该函数实现为:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
modCount 为ArrayList修改的次数,expectedModCount 为期望修改的次数,在删除第四个元素之前,modCount 和expectedModCount 均为4,而调用ArrayList的remove()方法后,modCount 变为5,但expectedModCount 仍为4,因此出现上述异常。
解决方法为:使用 Iterator的remove()方法取代ArrayList的remove()方法,可以避免ConcurrentModificationException异常。
巧合的是,如果要删除的元素正好是集合中倒数第二个元素,则不会抛出此异常。Iterator遍历获取一个元素之前会先调用hasNext()方法来判断是否还有元素,该方法实现为:
public boolean hasNext() {
return cursor != size();
}
其中cursor为遍历的位置,从0开始,在上面的next()方法中更新。
删除元素"3"后,cursor的值为3,而size()也返回3,hasNext()返回false,就不会调用next()方法了,因此也不存在ConcurrentModificationException异常。
删除元素"4"后,cursor的值变为4,而size()返回3,hasNext()返回true,调用next()方法时就会抛出ConcurrentModificationException异常。
附上一篇资料:
Java ConcurrentModificationException异常原因和解决方法:http://www.cnblogs.com/dolphin0520/p/3933551.html
java修改集合抛出ConcurrentModificationException异常
标签:
原文地址:http://my.oschina.net/u/1375259/blog/494668