前提,看一下这个
代码中的具体逻辑
- 创建Iterator迭代器的时候,第一步首先对expectedModCount进行赋值
int expectedModCount = modCount;
- 接下来调用hasNext方法,看是否有下一个对象,根据当前索引值是否等于迭代器长度进行控制
- 然后调用next()方法,返回list集合迭代器中当前索引值的元素.本方法中第一行代码是
checkForComodification();
检查模型修改次数是否和期望值相同 - 接下来调用迭代器的remove,add,set方法.在对元素进行修改的时候,对期望的修改次数进行了重新赋值,
expectedModCount = modCount;
- 意思就是如果使用迭代器自身的增删改方法,迭代器是会进行重新进行赋值.然后进行下一次迭代的时候,next()方法的第一行检查就会通过.
- 但是如果使用集合本身的方法进行了增删改操作,modCount++,但是迭代器不会对expectedModCount重新进行赋值.进行下一次迭代的时候,进行到next()方法第一行的时候,检查不通过,报错并发修改异常.
- 源码如下
包名java.util.AbstractList
/**
* {@inheritDoc}
*
* <p>This implementation returns a straightforward implementation of the
* {@code ListIterator} interface that extends the implementation of the
* {@code Iterator} interface returned by the {@code iterator()} method.
* The {@code ListIterator} implementation relies on the backing list's
* {@code get(int)}, {@code set(int, E)}, {@code add(int, E)}
* and {@code remove(int)} methods.
*
* <p>Note that the list iterator returned by this implementation will
* throw an {@link UnsupportedOperationException} in response to its
* {@code remove}, {@code set} and {@code add} methods unless the
* list's {@code remove(int)}, {@code set(int, E)}, and
* {@code add(int, E)} methods are overridden.
*
* <p>This implementation can be made to throw runtime exceptions in the
* face of concurrent modification, as described in the specification for
* the (protected) {@link #modCount} field.
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public ListIterator<E> listIterator(final int index) {
rangeCheckForAdd(index);
return new ListItr(index);
}
private class Itr implements Iterator<E> {
/**
* Index of element to be returned by subsequent call to next.
*/
int cursor = 0;
/**
* Index of element returned by most recent call to next or
* previous. Reset to -1 if this element is deleted by a call
* to remove.
*/
int lastRet = -1;
/**
* The modCount value that the iterator believes that the backing
* List should have. If this expectation is violated, the iterator
* has detected concurrent modification.
*/
int expectedModCount = modCount;//第一步
public boolean hasNext() {//第二步
return cursor != size();
}
public E next() {//第三步
checkForComodification();//3.1modCount模型修改次数检查
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;//增删改操作者,模型修改次数重新赋值
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
cursor = index;
}
public boolean hasPrevious() {
return cursor != 0;
}
public E previous() {
checkForComodification();
try {
int i = cursor - 1;
E previous = get(i);
lastRet = cursor = i;
return previous;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor-1;
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.set(lastRet, e);
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
AbstractList.this.add(i, e);
lastRet = -1;
cursor = i + 1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}