zoukankan      html  css  js  c++  java
  • AbstractList类_Iterator内部类

    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();
            }
        }
    }
    
  • 相关阅读:
    编写高质量代码改善C#程序的157个建议——建议68:从System.Exception或其他常见的基本异常中派生异常
    编写高质量代码改善C#程序的157个建议——建议67:慎用自定义异常
    编写高质量代码改善C#程序的157个建议——建议66:正确捕获多线程中的异常
    编写高质量代码改善C#程序的157个建议——建议65:总是处理未捕获的异常
    编写高质量代码改善C#程序的157个建议——建议64:为循环增加Tester-Doer模式而不是将try-catch置于循环内
    编写高质量代码改善C#程序的157个建议——建议63:避免“吃掉”异常
    编写高质量代码改善C#程序的157个建议——建议62:避免嵌套异常
    Django详细介绍
    Django【进阶篇 】
    Django【基础篇】
  • 原文地址:https://www.cnblogs.com/XiaoZhengYu/p/14093653.html
Copyright © 2011-2022 走看看