1.还原事故现场
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
Iterator<Integer> iterator = list.iterator();
ListIterator<Integer> integerListIterator = list.listIterator();
integerListIterator.next();
while (iterator.hasNext()){
Integer next = iterator.next();
if (next == 3){
list.remove(next);//java.util.ConcurrentModificationException
}
System.out.println(next);
}
2.解析
上面简单模拟了异常出现的情况,下面看看异常出现的原因,从
list.listIterator();
入手,点进去看看这个方法的返回值
public Iterator<E> iterator() {
return new Itr();
}
原来就是返回的Itr这个实现了Iterator接口的类
下面我们来看看这个类是怎么实现的,很简单(删减了和本次主题无关的东西)
private class Itr implements Iterator<E> {
//集合的大小
protected int limit = ArrayList.this.size;
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor < limit;
}
@SuppressWarnings("unchecked")
public E next() {
//这里是报异常的地方,也就是当modCount!=expectedModCount的时候会报异常
//我们看到,在这个类初始化的时候expectedModCount = modCount,
//在使用next()或者hasNext()方法的时候没有改变expectedModCount的值
//也就是说modCount的值改变,造成这两个值不一样了
//通过查看ArrayList的增删等方法,发现没操作一次增删等方法,这个modCount就++
//modCount就是记录的这个集合被修改的次数
//因此我们就明白了为什么在使用iterator迭代的时候不能修改
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
int i = cursor;
if (i >= limit)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
//但是我还想在迭代的时候进行删除操作怎么办?
//那么就用下面这个方法,这个方法进行删除操作仍然会保证modCount == expectedModCount
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
limit--;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
...
}
list除了iterator()方法还有一个list.listIterator()方法
这个方法返回的iterator功能更强大,比如可以增加一个值,可以更新一个值等
网友评论