并发修改异常
ConcurrentModificationException
异常名称: 并发修改异常
产生原因:
在使用迭代器迭代集合的同时,使用原集合修改元素
解决办法:
1.不使用迭代器遍历,使用普通for遍历
2.使用迭代器,但是使用列表迭代器
3.toArray
foreach是集合和数组的专属迭代器
Collection c=new ArrayList();
c.add("asd");
c.add("zxc");
c.add("qwe");
c.add("ert");
Iterator i=c.iterator();
//报错,因为迭代器迭代的同时,集合在修改元素, 并发异常
/* while(i.hasNext()){
String s=(String)i.next();
if(s.equals("zxc")){
c.remove("qwe");
}
}
*/
//并发报错
for (Object obj : c) {
String s = (String) obj;
if (s.equals("zxc")) {
c.remove("qwe");
}
并发异常原理:
在ArrayList中: 有trimToSize方法:
public void trimToSize() {
modCount++;//表示集合被修改的次数
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
在迭代器中有:
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
modCount //表示集合中记录其被修改的次数
expectedModCount//表示迭代器中记录其被修改的次数
这两个参数一般在迭代时使用
造成modCount字段改变的操作有:next、remove、previous、Set、add
如果你用迭代器又用集合操作,可能会导致两个数不同,产生异常。
(当exceptedModCount与modCount不相等时抛出异常)
如果你只单用迭代器,则这两个数的关系可以不考虑