ArrayList 源码分析

1)ArrayList 特点

  • List 接口的可变数组实现,ArrayList 允许使用任何元素,包括 null。
  • ArrayList 和 Vector 基本类似,只不过 Vector 是线程安全的,ArrayList 是线程不安全的。
  • size、isEmpty、get、set、iterator 和 listIterator 以常量时间运行,其他的操作基本以线性时间运行。
  • 每个 ArrayList 都有一个容量,容量表示该 ArrayList 当前能容纳的元素个数,随着元素的增加,ArrayList 会自动扩容。
  • 在创建 ArrayList 时可以指定一个合适的初始化容量,以减少频繁扩容带来的性能损耗。
  • ArrayList 是线程不安全的,多线程并发访问 ArrayList 并且至少有一个线程修改了它的结构【增加、删除元素、扩容等】,
    则 ArrayList 将抛出 ConcurrentModificationException 异常。
  • 快速失败机制:iterator 和 listIterator 返回的迭代器是快速失败的,如果不是通过 ListIterator#remove() 或 ListIterator#add(Object) 方法修改其结构,
    则 ArrayList 将尽最大努力抛出 ConcurrentModificationException 异常。
  • ArrayList 的缩容机制:通过 trimToSize 方法将 ArrayList 的容量缩小为当前元素的个数,以减少 ArrayList 的内存占用。
  • ArrayList 的扩容机制:默认为 1.5 倍向下取整扩容,如果批量添加元素,则以 size+newNum 进行扩容。

2)创建实例

    /**
     * ArrayList 底层存储元素的数组缓冲区
     */
    transient Object[] elementData;

    // 用于在空实例之间共享的空对象数组,用于简化扩容实现
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    
    // 创建容量为 10 的空 ArrayList 实例
    public ArrayList() {
        this.elementData = ArrayList.DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    /**
     * 基于用户指定的容量创建空 ArrayList 实例
     */
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            // 创建指定大小的对象数组
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            // 使用共享的空数组
            this.elementData = ArrayList.EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                    initialCapacity);
        }
    }

    /**
     * 基于指定的集合创建 ArrayList 实例
     */
    public ArrayList(Collection<? extends E> c) {
        // 集合转化为对象数组
        this.elementData = c.toArray();
        /**
         * 集合容量不为 0,并且类型不是 Object[].class,则将其转换为对象数组。
         */
        if ((this.size = this.elementData.length) != 0) {
            if (this.elementData.getClass() != Object[].class) {
                this.elementData = Arrays.copyOf(this.elementData, this.size, Object[].class);
            }
        } else {
            // 空集合默认使用共享空数组
            this.elementData = ArrayList.EMPTY_ELEMENTDATA;
        }
    }

3)在尾部添加元素

    /**
     *  【modCount 属性定义在 AbstractList 中】
     *  【ArrayList 被结构化修改的次数,结构化修改主要是改变 List 大小的操作】
     *  【该属性主要被 {@code iterator} and {@code listIterator} 方法返回的迭代器使用,
     *  用于在迭代器遍历元素时阻止并发修改带来的数据错误,如果此字段的值发生意外的更改,
     *  则迭代器将抛出 ConcurrentModificationException 异常。
     *  它实现了在列表出现并发修改时的快速失败机制。】
     */
    protected transient int modCount = 0;

    /**
     * 在 ArrayList 尾部新增元素
     */
    @Override
    public boolean add(E e) {
        modCount++;
        this.add(e, this.elementData, this.size);
        return true;
    }

    /**
     * 将方法字节码控制在 35(the -XX:MaxInlineSize default value) 个之内,以实现预编译和内联。
     */
    private void add(E e, Object[] elementData, int s) {
        // 如果当前元素个数和底层数组长度一致,则需要执行扩容
        if (s == elementData.length) {
            elementData = this.grow();
        }
        // 插入元素
        elementData[s] = e;
        // 增加元素个数
        this.size = s + 1;
    }

    /**
     * 默认每次增加一个空间,触发 1.5 倍向下取整扩容
     */
    private Object[] grow() {
        return this.grow(this.size + 1);
    }

    /**
     * 增加 ArrayList 的容量以满足最少能容纳 minCapacity 个元素
     */
    private Object[] grow(int minCapacity) {
        // 基于数组拷贝实现扩容
        return this.elementData = Arrays.copyOf(this.elementData,
                this.newCapacity(minCapacity));
    }

    /**
     * 可分配的最大数组大小
     */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
     * 基于预期容量计算新的容量
     */
    private int newCapacity(int minCapacity) {
        // overflow-conscious code
        final int oldCapacity = this.elementData.length;
        /**
         * 1.5 倍向下取整扩容
         */
        final int newCapacity = oldCapacity + (oldCapacity >> 1);
        /**
         * 默认扩容后的容量小于预期容量,则以预期容量为准
         */
        if (newCapacity - minCapacity <= 0) {
            // 第一次扩容时,取 10 和 minCapacity 的最大值
            if (this.elementData == ArrayList.DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                return Math.max(ArrayList.DEFAULT_CAPACITY, minCapacity);
            }
            // 预期容量溢出
            if (minCapacity < 0) {
                throw new OutOfMemoryError();
            }
            return minCapacity;
        }
        /**
         * 新的容量小于等于 Integer.MAX_VALUE - 8 则直接返回,
         * 否则基于预期容量返回 Integer.MAX_VALUE - 8 或 Integer.MAX_VALUE
         */
        return newCapacity - ArrayList.MAX_ARRAY_SIZE <= 0
                ? newCapacity
                        : ArrayList.hugeCapacity(minCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        // 预期容量已经溢出,则抛出 OutOfMemoryError
        if (minCapacity < 0) {
            throw new OutOfMemoryError();
        }
        return minCapacity > ArrayList.MAX_ARRAY_SIZE
                ? Integer.MAX_VALUE
                        : ArrayList.MAX_ARRAY_SIZE;
    }

4)在指定索引处添加元素

    /**
     * 在指定的位置插入元素
     */
    @Override
    public void add(int index, E element) {
        this.rangeCheckForAdd(index);
        modCount++;
        final int s;
        Object[] elementData;
        // 当前元素个数等于底层数组容量,则执行扩容
        if ((s = this.size) == (elementData = this.elementData).length) {
            elementData = this.grow();
        }
        // 将目标索引处的元素集体右移一个位置
        System.arraycopy(elementData, index,
                elementData, index + 1,
                s - index);
        // 将新元素更新到目标索引处
        elementData[index] = element;
        // 递增元素个数值
        this.size = s + 1;
    }

    private void rangeCheckForAdd(int index) {
        if (index > this.size || index < 0) {
            throw new IndexOutOfBoundsException(this.outOfBoundsMsg(index));
        }
    }

5)将集合中的元素顺序加入到 ArrayList 尾部

    /**
     * 将集合中的元素顺序加入到 ArrayList 尾部
     */
    @Override
    public boolean addAll(Collection<? extends E> c) {
        final Object[] a = c.toArray();
        modCount++;
        // 获取需要添加的元素总个数
        final int numNew = a.length;
        // 集合为空则直接返回
        if (numNew == 0) {
            return false;
        }
        Object[] elementData;
        final int s;
        // 新增元素个数大于 ArrayList 的剩余容量,则执行扩容,预期容量为 size+newNum
        if (numNew > (elementData = this.elementData).length - (s = this.size)) {
            elementData = this.grow(s + numNew);
        }
        // 将集合中的元素拷贝到 elementData 数组中
        System.arraycopy(a, 0, elementData, s, numNew);
        // 增加总元素个数
        this.size = s + numNew;
        return true;
    }

6)获取指定索引处的元素

    /**
     * 获取指定索引处的元素
     */
    @Override
    public E get(int index) {
        // 下标校验
        Objects.checkIndex(index, this.size);
        return this.elementData(index);
    }

    // 位置访问操作
    /**
     * 获取指定索引处的元素
     * created by ZXD at 15 Jul 2018 T 11:28:00
     * @param index
     * @return
     */
    E elementData(int index) {
        return (E) this.elementData[index];
    }

7)替换指定索引处的元素,并返回旧值

    /**
     * 替换指定索引处的元素,并返回旧值
     */
    @Override
    public E set(int index, E element) {
        // 下标校验
        Objects.checkIndex(index, this.size);
        // 读取旧值
        final E oldValue = this.elementData(index);
        // 更新新值
        this.elementData[index] = element;
        // 返回旧值
        return oldValue;
    }

8)移除指定索引处的元素

    /**
     * 移除指定索引处的元素
     */
    @Override
    public E remove(int index) {
        // 下标校验
        Objects.checkIndex(index, this.size);
        final Object[] es = this.elementData;

        @SuppressWarnings("unchecked")
        final E oldValue = (E) es[index];
        this.fastRemove(es, index);

        return oldValue;
    }

    /**
     * 移除元素时,跳过索引校验并且不返回旧元素的值
     */
    private void fastRemove(Object[] es, int i) {
        modCount++;
        final int newSize;
        // 计算新的 size 值,如果 size 值大于目标索引
        if ((newSize = this.size - 1) > i) {
            // 如果移除索引在数组中间,则目标索引处右侧的元素集体左移一个单位
            System.arraycopy(es, i + 1, es, i, newSize - i);
        }
        // 将最后一个元素置为 null
        es[this.size = newSize] = null;
    }

9)移除指定的目标元素

    /**
     * 通过 {@link Object#equals(Object)} 方法获取第一个匹配的元素并移除
     */
    @Override
    public boolean remove(Object o) {
        final Object[] es = this.elementData;
        final int size = this.size;
        int i = 0;
        // 首先获取目标元素的索引
        found: {
            if (o == null) {
                for (; i < size; i++) {
                    if (es[i] == null) {
                        break found;
                    }
                }
            } else {
                for (; i < size; i++) {
                    if (o.equals(es[i])) {
                        break found;
                    }
                }
            }
            return false;
        }
        // 快速移除目标元素
        this.fastRemove(es, i);
        return true;
    }

10)移除指定索引间的元素

    /**
     * 移除指定索引范围内的所有元素,包括开始索引,不包括结束索引
     */
    @Override
    protected void removeRange(int fromIndex, int toIndex) {
        if (fromIndex > toIndex) {
            throw new IndexOutOfBoundsException(
                    ArrayList.outOfBoundsMsg(fromIndex, toIndex));
        }
        modCount++;
        this.shiftTailOverGap(this.elementData, fromIndex, toIndex);
    }

    /** Erases the gap from lo to hi, by sliding down following elements. */
    private void shiftTailOverGap(Object[] es, int lo, int hi) {
        System.arraycopy(es, hi, es, lo, this.size - hi);
        for (int to = this.size, i = this.size -= hi - lo; i < to; i++) {
            es[i] = null;
        }
    }

11)移除 ArrayList 中包含在目标集合中的所有元素

    /**
     * 移除 ArrayList 中包含在目标集合中的所有元素,通过 {@link Object#equals(Object)} 进行相等性判断
     */
    @Override
    public boolean removeAll(Collection<?> c) {
        return this.batchRemove(c, false, 0, this.size);
    }

    /**
     * created by ZXD at 30 Aug 2018 T 22:16:52
     * @param c 目标集合
     * @param complement    ArrayList 中的元素需要移除还是保留,false 表示移除,true 表示保留
     * @param from  开始索引
     * @param end   结束索引
     * @return
     */
    boolean batchRemove(Collection<?> c, boolean complement,
            final int from, final int end) {
        Objects.requireNonNull(c);
        // 暂存底层数组
        final Object[] es = this.elementData;
        int r;
        // Optimize for initial run of survivors
        for (r = from;; r++) {
            // 如果已经全部遍历完,没有需要处理的元素,则直接返回
            if (r == end) {
                return false;
            }
            // 找到第一个需要丢弃的元素下标
            if (c.contains(es[r]) != complement) {
                break;
            }
        }
        // 暂存需要处理元素的下一个位置
        int w = r++;
        try {
            // 遍历余下的所有元素
            for (Object e; r < end; r++) {
                // 保留满足条件的目标元素
                if (c.contains(e = es[r]) == complement) {
                    es[w++] = e;
                }
            }
        } catch (final Throwable ex) {
            // Preserve behavioral compatibility with AbstractCollection,
            // even if c.contains() throws.
            System.arraycopy(es, r, es, w, end - r);
            w += end - r;
            throw ex;
        } finally {
            // 修改并发计数值
            modCount += end - w;
            this.shiftTailOverGap(es, w, end);
        }
        return true;
    }

12)只保留 ArrayList 中包含在目标集合中的所有元素

    /**
     * 保留 ArrayList 中包含在目标集合中的所有元素,通过 {@link Object#equals(Object)} 进行相等性判断
     */
    @Override
    public boolean retainAll(Collection<?> c) {
        return this.batchRemove(c, true, 0, this.size);
    }

13)从头开始遍历元素,返回第一个和目标元素相等的元素索引,如果不存在,则返回 -1。

    /**
     * 从头开始遍历元素,返回第一个和目标元素相等的元素索引,如果不存在,则返回 -1
     */
    @Override
    public int indexOf(Object o) {
        /**
         * 返回第一个匹配元素的索引
         */
        if (o == null) {
            for (int i = 0; i < this.size; i++) {
                if (this.elementData[i]==null) {
                    return i;
                }
            }
        } else {
            for (int i = 0; i < this.size; i++) {
                if (o.equals(this.elementData[i])) {
                    return i;
                }
            }
        }
        return -1;
    }

14)从尾部开始遍历元素,返回第一个和目标元素相等的元素索引,如果不存在,则返回 -1。

    /**
            * 从尾部开始遍历元素,返回第一个和目标元素相等的元素索引,如果不存在,则返回 -1
     */
    @Override
    public int lastIndexOf(Object o) {
        /**
         * 返回第一个匹配元素的索引
         */
        if (o == null) {
            for (int i = this.size-1; i >= 0; i--) {
                if (this.elementData[i]==null) {
                    return i;
                }
            }
        } else {
            for (int i = this.size-1; i >= 0; i--) {
                if (o.equals(this.elementData[i])) {
                    return i;
                }
            }
        }
        return -1;
    }

15)ArrayList 中是否包含和目标元素相等的元素,如果包含,则返回 true;否则返回 false。

    /**
            * 从头开始遍历,并通过 {@link Object#equals(Object)} 方法获取相等元素的索引
     */
    @Override
    public boolean contains(Object o) {
        return this.indexOf(o) >= 0;
    }

16)ArrayList 中当前元素的个数

    /**
     * 当前元素个数
     * created by ZXD at 15 Jul 2018 T 11:25:21
     * @return
     */
    @Override
    public int size() {
        return this.size;
    }

17)ArrayList 是否为空

    /**
          * 是否为空
     * created by ZXD at 15 Jul 2018 T 11:25:48
     * @return
     */
    @Override
    public boolean isEmpty() {
        return this.size == 0;
    }

18)将 ArrayList 的容量缩小为当前元素的个数,以减少 ArrayList 的内存占用,适合于静态 ArrayList 实例。

    /**
        *  将 ArrayList 的容量缩小为当前元素的个数,以减少 ArrayList 的内存占用。
     */
    public void trimToSize() {
        // 结构修改计数器
        modCount++;
        /**
         * 当元素个数小于对象数组长度时,缩小其容量为元素个数,降低 ArrayList 的内存占用。
         */
        if (this.size < this.elementData.length) {
            this.elementData = this.size == 0
                    ? ArrayList.EMPTY_ELEMENTDATA
                            : Arrays.copyOf(this.elementData, this.size);
        }
    }

19)如果需要,则增加 ArrayList 的容量以满足最少能容纳 minCapacity 个元素。

    /**
     * 增加 ArrayList 的容量以满足最少能容纳 minCapacity 个元素
     */
    public void ensureCapacity(int minCapacity) {
        /**
         * 预期容量大于可用容量时执行扩容操作
         */
        if (minCapacity > this.elementData.length
                && !(this.elementData == ArrayList.DEFAULTCAPACITY_EMPTY_ELEMENTDATA
                && minCapacity <= ArrayList.DEFAULT_CAPACITY)) {
            modCount++;
            this.grow(minCapacity);
        }
    }

20)将 ArrayList 转换为指定类型的对象数组,包含所有元素。

    @Override
    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        /**
         * 形参数组的长度小于 ArrayList 的 size,则默认复制 ArrayList 的所有元素,
         * 长度为 ArrayList 的 size。
         */
        if (a.length < this.size) {
            return (T[]) Arrays.copyOf(this.elementData, this.size, a.getClass());
        }
        System.arraycopy(this.elementData, 0, a, 0, this.size);
        /**
         * 复制 ArrayList 的所有元素,并将索引为 size 的元素设置为 null,返回新数组
         */
        if (a.length > this.size) {
            a[this.size] = null;
        }
        return a;
    }

21)将 ArrayList 实例转换为 Object 对象数组

    /**
     * 返回包含 ArrayList 所有元素的对象数组
     */
    @Override
    public Object[] toArray() {
        // 拷贝出 ArrayList 中存储在底层对象数组中的所有元素
        return Arrays.copyOf(this.elementData, this.size);
    }

22)使用函数式接口顺序消费 ArrayList 中的每个元素,出现并发修改时,之前消费的元素不能回滚

    /**
     * 顺序消费 ArrayList 中的每个元素
     */
    @Override
    public void forEach(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        // 缓存并发修改计数值
        final int expectedModCount = modCount;
        // 读取底层对象数组
        final Object[] es = this.elementData;
        // 读取元素个数
        final int size = this.size;
        // 遍历每个元素并调用函数式接口进行消费
        for (int i = 0; modCount == expectedModCount && i < size; i++) {
            action.accept(ArrayList.elementAt(es, i));
        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }

23)移除 ArrayList 中满足指定函数式断言的所有元素

    /**
     * 移除 ArrayList 中满足指定函数式断言的所有元素
     */
    @Override
    public boolean removeIf(Predicate<? super E> filter) {
        return this.removeIf(filter, 0, this.size);
    }

    /**
     * Removes all elements satisfying the given predicate, from index
     * i (inclusive) to index end (exclusive).
     *  【移除所有满足指定断言的元素,包括起始索引,不包括结束索引】
     */
    boolean removeIf(Predicate<? super E> filter, int i, final int end) {
        Objects.requireNonNull(filter);
        int expectedModCount = modCount;
        final Object[] es = this.elementData;
        /**
         *  从头开始略过不满足断言的元素,找到第一个需要移除的元素索引
         */
        for (; i < end && !filter.test(ArrayList.elementAt(es, i)); i++) {
            ;
        }
        // Tolerate predicates that reentrantly access the collection for
        // read (but writers still get CME), so traverse once to find
        // elements to delete, a second pass to physically expunge.
        if (i < end) {
            final int beg = i;
            final long[] deathRow = ArrayList.nBits(end - beg);
            deathRow[0] = 1L;   // set bit 0
            for (i = beg + 1; i < end; i++) {
                if (filter.test(ArrayList.elementAt(es, i))) {
                    ArrayList.setBit(deathRow, i - beg);
                }
            }
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            expectedModCount++;
            modCount++;
            int w = beg;
            for (i = beg; i < end; i++) {
                if (ArrayList.isClear(deathRow, i - beg)) {
                    es[w++] = es[i];
                }
            }
            this.shiftTailOverGap(es, w, end);
            return true;
        } else {
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            return false;
        }
    }

24)将 ArrayList 中的所有元素替换为通过二元函数式接口变换后的值,元素类型保持不变。

    /**
     * UnaryOperator 接受类型为 E 的参数并返回类型为 E 的对象
     */
    @Override
    public void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        final int expectedModCount = modCount;
        final Object[] es = this.elementData;
        final int size = this.size;
        for (int i = 0; modCount == expectedModCount && i < size; i++) {
            // 遍历并替换 ArrayList 中的每个元素
            es[i] = operator.apply(ArrayList.elementAt(es, i));
        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
        modCount++;
    }

25)通过指定的比较器对 ArrayList 中的元素执行排序

    /**
     * 对 ArrayList 进行排序
     */
    @Override
    @SuppressWarnings("unchecked")
    public void sort(Comparator<? super E> c) {
        final int expectedModCount = modCount;
        // 对对象数组内指定范围的元素执行排序
        Arrays.sort((E[]) this.elementData, 0, this.size, c);
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
        modCount++;
    }

26)返回 ArrayList 的顺序迭代器

    /**
     * 返回 ArrayList 的顺序迭代器
     */
    @Override
    public Iterator<E> iterator() {
        return new Itr();
    }

    /**
     * An optimized version of AbstractList.Itr
     * 只能往后遍历,支持移除元素
     */
    private class Itr implements Iterator<E> {
        int cursor;       // 下一个返回元素的索引,从 0 开始
        int lastRet = -1; // 最近一个返回元素的索引
        int expectedModCount = ArrayList.this.modCount; // fast-fail 机制的计数器

        Itr() {}

        /**
         * 是否还有下一个元素
         * created by ZXD at 15 Jul 2018 T 11:39:55
         * @return
         */
        @Override
        public boolean hasNext() {
            return this.cursor != ArrayList.this.size;
        }

        /**
         * 获取下一个元素
         * created by ZXD at 15 Jul 2018 T 11:40:12
         * @return
         */
        @Override
        @SuppressWarnings("unchecked")
        public E next() {
            /**
             * 并发修改校验,创建迭代器时会获取外部修改计数器值并将其缓存,
             * 通过比较缓存值和外部计数器值来判断是否发生并发结构修改。
             */
            this.checkForComodification();
            // 获取下一个元素的索引
            final int i = this.cursor;
            // 元素已经全部遍历完成,并发遍历时其中有线程删除了元素时可能出现
            if (i >= ArrayList.this.size) {
                throw new NoSuchElementException();
            }
            final Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length) {
                throw new ConcurrentModificationException();
            }
            // 递增游标值
            this.cursor = i + 1;
            // 返回目标值
            return (E) elementData[this.lastRet = i];
        }

        @Override
        public void remove() {
            if (this.lastRet < 0) {
                throw new IllegalStateException();
            }
            this.checkForComodification();

            try {
                // 移除 ArrayList 中的元素
                ArrayList.this.remove(this.lastRet);
                // 更新游标值
                this.cursor = this.lastRet;
                // 移除元素时,lastRet 置为 -1
                this.lastRet = -1;
                // 更新内部的并发修改计数值
                this.expectedModCount = ArrayList.this.modCount;
            } catch (final IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        /**
         * 顺序消费未迭代的所有元素
         * created by ZXD at 15 Jul 2018 T 11:44:41
         * @param action
         */
        @Override
        public void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            final int size = ArrayList.this.size;
            int i = this.cursor;
            if (i < size) {
                final Object[] es = ArrayList.this.elementData;
                if (i >= es.length) {
                    throw new ConcurrentModificationException();
                }
                // 游标值小于 size 并且未发生并发结构修改
                for (; i < size && ArrayList.this.modCount == this.expectedModCount; i++) {
                    // 使用函数式接口消费目标元素
                    action.accept(ArrayList.elementAt(es, i));
                }
                // update once at end to reduce heap write traffic
                // 更新游标值
                this.cursor = i;
                this.lastRet = i - 1;
                this.checkForComodification();
            }
        }

        final void checkForComodification() {
            /**
             * 判断是否存在多线程并发修改 ArrayList 实例
             */
            if (ArrayList.this.modCount != this.expectedModCount) {
                throw new ConcurrentModificationException();
            }
        }
    }

27)返回 ArrayList 的列表迭代器

    /**
     * 返回 ArrayList 的列表迭代器
     */
    @Override
    public ListIterator<E> listIterator() {
        return new ListItr(0);
    }

    /**
     * An optimized version of AbstractList.ListItr
     * 支持向前或向后遍历,支持在迭代过程中增加、移除、修改元素
     */
    private class ListItr extends Itr implements ListIterator<E> {
        ListItr(int index) {
            super();
            cursor = index;
        }

        /**
         * 是否存在可迭代的前一个元素
         * created by ZXD at 15 Jul 2018 T 11:47:17
         * @return
         */
        @Override
        public boolean hasPrevious() {
            return cursor != 0;
        }

        /**
         * 获取下一个迭代元素的索引
         * created by ZXD at 15 Jul 2018 T 11:47:45
         * @return
         */
        @Override
        public int nextIndex() {
            return cursor;
        }

        /**
         * 获取前一个迭代元素的索引
         * created by ZXD at 15 Jul 2018 T 11:48:02
         * @return
         */
        @Override
        public int previousIndex() {
            return cursor - 1;
        }

        /**
         * 获取前一个迭代元素
         * created by ZXD at 15 Jul 2018 T 11:48:20
         * @return
         */
        @Override
        @SuppressWarnings("unchecked")
        public E previous() {
            checkForComodification();
            final int i = cursor - 1;
            if (i < 0) {
                throw new NoSuchElementException();
            }
            final Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length) {
                throw new ConcurrentModificationException();
            }
            // 更新游标并返回目标元素
            cursor = i;
            return (E) elementData[lastRet = i];
        }

        /**
         * 更新最后一次返回的元素
         * created by ZXD at 15 Jul 2018 T 11:49:59
         * @param e
         */
        @Override
        public void set(E e) {
            if (lastRet < 0) {
                throw new IllegalStateException();
            }
            checkForComodification();

            try {
                ArrayList.this.set(lastRet, e);
            } catch (final IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        /**
         * 迭代过程中动态将元素插入到下一次迭代的索引处
         * created by ZXD at 15 Jul 2018 T 11:50:25
         * @param e
         */
        @Override
        public void add(E e) {
            checkForComodification();

            try {
                final int i = cursor;
                ArrayList.this.add(i, e);
                // 更新游标、最后一次返回的元素下标、结构修改计数值
                cursor = i + 1;
                lastRet = -1;
                expectedModCount = ArrayList.this.modCount;
            } catch (final IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }

28)清空 ArrayList

    /**
     * 清空数组元素和 size
     */
    @Override
    public void clear() {
        modCount++;
        final Object[] es = this.elementData;
        // 将对象数组前 size 个元素置为 null
        for (int to = this.size, i = this.size = 0; i < to; i++) {
            es[i] = null;
        }
    }

posted on 2018-09-03 21:11 竺旭东 阅读() 评论() 编辑 收藏

版权声明:本文为zhuxudong原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/zhuxudong/p/9581072.html