AbstractList类_Iterator内部类
1. 源码
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
/**
* The number of times this list has been <i>structurally modified</i>.
* Structural modifications are those that change the size of the
* list, or otherwise perturb it in such a fashion that iterations in
* progress may yield incorrect results.
*
* <p>This field is used by the iterator and list iterator implementation
* returned by the {@code iterator} and {@code listIterator} methods.
* If the value of this field changes unexpectedly, the iterator (or list
* iterator) will throw a {@code ConcurrentModificationException} in
* response to the {@code next}, {@code remove}, {@code previous},
* {@code set} or {@code add} operations. This provides
* <i>fail-fast</i> behavior, rather than non-deterministic behavior in
* the face of concurrent modification during iteration.
*
* <p><b>Use of this field by subclasses is optional.</b> If a subclass
* wishes to provide fail-fast iterators (and list iterators), then it
* merely has to increment this field in its {@code add(int, E)} and
* {@code remove(int)} methods (and any other methods that it overrides
* that result in structural modifications to the list). A single call to
* {@code add(int, E)} or {@code remove(int)} must add no more than
* one to this field, or the iterators (and list iterators) will throw
* bogus {@code ConcurrentModificationExceptions}. If an implementation
* does not wish to provide fail-fast iterators, this field may be
* ignored.
*/
protected transient int modCount = 0;
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();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException(e);
}
}
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();
}
}
}
2. 笔记
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
/**
* 统计 List 发生“结构修改”的次数。结构修改是指更改 List 大小或其他可能影响当前
* Iterator 的操作 List 的行为。
*/
protected transient int modCount = 0;
private class Itr implements Iterator<E> {
/**
* 下一个将要被遍历到的集合元素的索引
*/
int cursor = 0;
/**
* 最后一次调用 next() 方法返回的集合元素的的索引。如果这个集合元素已经通过
* remove() 方法删除,lastRet 的值将被置为 -1。
*/
int lastRet = -1;
/**
* 假如当前 Iterator 生成以后,除了当前 Iterator ,外界不对底层 List 进行
* 任何“结构修改”,底层 List 应该具有的“结构修改”次数(生成当前 Iterator 时
* 已经具有的修改次数 + 当前 Iterator 的修改次数)。
* <p>
* 当前 Iterator 在对底层集合进行“结构修改”时,会同时累加 expectedModCount
* 和 modCount 的值,所以一旦 expectedModCount 和 modCount 的值变得不一致,
* 说明外界对底层集合进行了“结构修改”,这就存在集合并发访问的问题。
*/
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size();
}
public E next() {
// 1.并发访问校验
checkForComodification();
// 2.获取集合元素
try {
int i = cursor;
// 可能越界访问
E next = get(i);
// 每调用一次 next() 方法,只允许调用一次 remove() 方法。
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
/*
* 导致越界访问可能有两种原因:
* 1.当前 Iterator 确实已经遍历完了底层集合中的所有元素
* 2.外界对底层集合进行了“结构修改”
*/
checkForComodification();
throw new NoSuchElementException(e);
}
}
public void remove() {
// 每调用一次 next() 方法,只允许调用一次 remove() 方法。
if (lastRet < 0)
throw new IllegalStateException();
/*
* 如果外界对底层集合进行了“结构修改”,此时如果继续执行 remove() 方法,可能无法
* 达到调用者预期的目标:remove() 方法通过 next() 方法保存的元素索引值来删除集
* 合中的元素,此时已经无法保证这个索引值还是之前调用 next() 方法返回的集合元素。
*/
checkForComodification();
try {
AbstractList.this.remove(lastRet);
/*
* 删除元素后,底层集合的大小已经发生了改变,因此需要调整 cursor 的值以确保再次
* 调用 next() 时能够返回正确的集合元素。
*/
if (lastRet < cursor)
cursor--;
// 每调用一次 next() 方法,只允许调用一次 remove() 方法。
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}
地势坤,君子以厚德载物。