0
点赞
收藏
分享

微信扫一扫

使用Iterator出现错误ConcurrentModificationException


使用Iterator出现错误ConcurrentModificationException_iterator


这是因为这个itertor是通过c.iterator()获得的。也就是说目前Iterator中的数据是已知固定的,再次添加或者删除就会导致问题,细心的话可能会注意到报错并不是在15行而是在18行也就是next()方法所在的这一行。

看源码可知

public boolean hasNext() { 
return cursor != size();
}
public E next() {
//系统调用了这个方法
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
//发生异常的时候也调用了此方法
checkForComodification();
throw new NoSuchElementException();
}
}
看一眼系统中的这个方法checkForComodification();
//有一个modCount != expectedModCount的对比
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
那么这两个参数modCount和expectedModCount都代表什么意思呢?
继续跟踪这两个变量,在Itr类的成员变量里对expectedModCount初始化的赋值是int expectedModCount = modCount;
那么这个modCount呢.? 这个是AbstractList中的一个protected的变量, 在对集合增删的操作中均对modCount做了修改, 因为这里是拿ArrayList为例, 所以直接看ArrayList中有没有覆盖父类的add.? 结果发现覆盖了
public boolean add(E e) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
}


remove方法中也做了modCount++, 当我获得迭代器之前, 无论对集合做了多少次添加删除操作, 都没有关系, 因为对expectedModCount赋值是在获取迭代器的时候初始化的!

也就是说, 如果我对集合添加删除一共操作了100次,此时modCount为100, 获取迭代器的时候expectedModCount也为100, 迭代期间会去checkForComodification()! 只要在next或者remove之前有对集合操作的动作导致modCount发生了改变, 就会抛那个并发修改异常!

最后得出的结论就是:在迭代器声明后,没有完全迭代完全,就不要在操作集合的数据了。


举报

相关推荐

0 条评论