ArrayList并发修改异常
遇到这么个问题:迭代器并发修改会抛出异常,这个问题之前没有遇到过,特意记录一下:
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<String>();
//添加元素
list.add("hello");
list.add("Java");
list.add("PHP");
//获取迭代器
Iterator<String> it = list.iterator();
//遍历集合
while (it.hasNext()) {
System.out.println(list);
String s = it.next();
System.out.println(s);
if(s.equals("PHP")) {
list.remove("PHP");
}
}
}
}
/**
* [hello, Java, PHP]
* hello
* [hello, Java, PHP]
* Java
* [hello, Java, PHP]
* PHP
* [hello, Java]
* 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.lcg.collection.arryList.iteratorDemo.Test02.main(Test02.java:28)
*/
从结果中可以看到异常是从checkForComodification方法中抛出的,而抛出该异常的条件是modCount 与expectedModCount不相等。从结果中看出虽然报异常了,但是我们想要删除的PHP元素也删除了。所以这个异常是从删除后的下一次集合调用next方法产生的。至于为什么会出现异常也就是modCount 与expectedModCount不相等原因是因为集合的remove方法中会对集合成员变量modCount和size进行修改,调用集合的remove方法后再调用next方法时此时的modCount 与expectedModCount就会不相等所以就会报异常。其实ArrayList集合不仅是remove方法会修改modCount值,其他比如add(),clear()等方法都会修改modCount。
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<String>();
//添加元素
list.add("hello");
list.add("PHP");
list.add("Java");
//获取迭代器
Iterator<String> it = list.iterator();
//遍历集合
while (it.hasNext()) {
String s = it.next();
if(s.equals("hello")) {
it.remove();
}
}
System.out.println(list);
//[PHP, Java]
}
调用迭代器中的remove方法不会有异常的原因是迭代器中的remove方法中对expectedModCount方法进行了重新赋值即expectedModCount = modCount,所以就不会出现expectedModCount与modCount不相等的情况了。