AbstractList类_Iterator内部类


AbstractList类_Iterator内部类


1. 源码

public abstract class AbstractList extends AbstractCollection implements List {
   /**
     * The number of times this list has been structurally modified.
     * 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.
     *
     * 

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 * fail-fast behavior, rather than non-deterministic behavior in * the face of concurrent modification during iteration. * *

Use of this field by subclasses is optional. 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 { /** * 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 extends AbstractCollection implements List {

    /**
     * 统计 List 发生“结构修改”的次数。结构修改是指更改 List 大小或其他可能影响当前
     * Iterator 的操作 List 的行为。
     */
    protected transient int modCount = 0;

    private class Itr implements Iterator {
        /**
         * 下一个将要被遍历到的集合元素的索引
         */
        int cursor = 0;

        /**
         * 最后一次调用 next() 方法返回的集合元素的的索引。如果这个集合元素已经通过
         * remove() 方法删除,lastRet 的值将被置为 -1。
         */
        int lastRet = -1;

        /**
         * 假如当前 Iterator 生成以后,除了当前 Iterator ,外界不对底层 List 进行
         * 任何“结构修改”,底层 List 应该具有的“结构修改”次数(生成当前 Iterator 时
         * 已经具有的修改次数 + 当前 Iterator 的修改次数)。
         * 

* 当前 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(); } } }