ArrayList源码研读

ArrayList源码研读

属性

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
        /*
         * (序列化(Serializable接口)
         *
         *  含义:将一个对象的状态(各个属性值)保存起来,然后在适当的时候再获得
         *
         *  用途:序列化的过程就是对象写入字节流(序列化)和从字节流中读取对象(反序列化),
         * 允许一个对象在虚拟机之间传送(或者经过一段空间,如在RMI中;或者经过一段时间,比如数据流被保存到一个文件中)。
         * 对象序列化可以对对象进行深层复制。
         *
         *  Java对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,
         * 并能够以后将这个字节序列完全恢复为原来的对象。利用对象的序列化,可以实现轻量级持久性,
         * 这意味着一个对象的生存周期并不取决于程序是否正在执行,它可以生存于程序的调用之间。
         * 通过将一个序列化对象写入磁盘,然后在重新调用程序时恢复该对象,就能够实现持久性的效果。
         *
         */ {
    private static final long serialVersionUID = 8683452581122892189L;

    /**
     * Default initial capacity.
     * 默认容量10
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * Shared empty array instance used for empty instances.
     * 空数组实例
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     * 默认容量实例
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * 存储ArrayList的元素的数组缓冲区
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     * ArrayList的容量是该数组缓冲区的长度。
     * 添加第一个元素时,任何具有elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空ArrayList都将扩展为默认容量。
     * elementData属性采用了transient来修饰,表明其不使用Java默认的序列化机制来实例化
     * elementData里面有一些元素是空的,这种是没有必要序列化的。
     * ArrayList的序列化和反序列化依赖writeObject和readObject方法来实现。可以避免序列化空的元素。
     */
    transient Object[] elementData; // non-private to simplify nested class access

    /**
     * The size of the ArrayList (the number of elements it contains).
     */
    private int size;

构造器

public ArrayList (int initialCapacity)

public ArrayList ()

public ArrayList (Collection<? extends E> c)

   /**
     * Constructs an empty list with the specified initial capacity.
     * 以指定初始容量构造一个空的集合
     * @param initialCapacity
     *         the initial capacity of the list
     *
     * @throws IllegalArgumentException
     *         if the specified initial capacity
     *         is negative
     */
    public ArrayList (int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException ("Illegal Capacity: " +
                    initialCapacity);
        }
    }

    /**
     * Constructs an empty list with an initial capacity of ten.
     * (不指定初始容量时)以默认初始容量10构造一个空的集合
     */
    public ArrayList () {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     * 构造一个包含指定集合的元素的列表,该列表按集合的迭代顺序排列。
     * @param c
     *         the collection whose elements are to be placed into this list
     *
     * @throws NullPointerException
     *         if the specified collection is null
     */
    public ArrayList (Collection<? extends E> c) {
        elementData = c.toArray ();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass () != Object[].class)
                elementData = Arrays.copyOf (elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

容量削减

public void trimToSize ()

  /**
     * Trims the capacity of this <tt>ArrayList</tt> instance to be the
     * list's current size.  An application can use this operation to minimize
     * the storage of an <tt>ArrayList</tt> instance.
     * 将此ArrayList实例的容量削减为
     * list的当前大小。
     * 程序可以使用此操作最小化ArrayList实例的存储。
     */
    public void trimToSize () {
        modCount++;
        if (size < elementData.length) {
            elementData = (size == 0)
                    ? EMPTY_ELEMENTDATA
                    : Arrays.copyOf (elementData, size);
        }
    }

扩容

ensureCapacity (int minCapacity)

calculateCapacity (Object[] elementData, int minCapacity)

ensureCapacityInternal (int minCapacity)

ensureExplicitCapacity (int minCapacity)

grow (int minCapacity)

  /**
     * Increases the capacity of this <tt>ArrayList</tt> instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     * 扩容
     *
     * @param minCapacity
     *         the desired minimum capacity
     */
    public void ensureCapacity (int minCapacity) {
        //判断需要扩容的数组是否为空实例(空数组)如果为不为空,则变量等于0.为空则变量等于数组默认容量 10
        int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY;
        // any size if not default element table
        // larger than default for default empty table. It's already
        // supposed to be at default size.
        //如果需要扩容的量大于定义的变量。则进一步调用以下方法。
        if (minCapacity > minExpand) {
            ensureExplicitCapacity (minCapacity);
        }
    }

    /**
     * 计算需要的容量
     */
    private static int calculateCapacity (Object[] elementData, int minCapacity) {
        //如果传进来的elementData是DEFAULTCAPACITY_EMPTY_ELEMENTDATA
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {

            // 获取默认的容量和传入参数的较大值
            return Math.max (DEFAULT_CAPACITY, minCapacity);
        }
        //直接返回需要的最小容量
        return minCapacity;
    }

    /**
     * 确认需要扩容的容量并进行扩容
     * @param minCapacity
     */
    private void ensureCapacityInternal (int minCapacity) {
        ensureExplicitCapacity (calculateCapacity (elementData, minCapacity));
    }

    /**
     * 进行扩容
     * @param minCapacity
     */
    private void ensureExplicitCapacity (int minCapacity) {
        //改变了list的大小
        modCount++;
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            //扩容
            grow (minCapacity);
    }

    /**
     * The maximum size of array to allocate.
     * Some VMs reserve some header words in an array.
     * 某些虚拟机需要8字节存储头信息
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     * 最大size
     */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity
     *         the desired minimum capacity(需要扩容到的最小容量)
     */
    private void grow (int minCapacity) {
        // overflow-conscious code
        //旧容量
        int oldCapacity = elementData.length;
        //新容量 = o+o/2 就是1.5倍的old
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //扩容后没达到需要扩容到的最小容量,扩容到minCapacity
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //新容量大于MAX_ARRAY_SIZE(Integer.MAX_VALUE - 8)
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            //扩容到Integer.MAX_VALUE 
            newCapacity = hugeCapacity (minCapacity);
        // minCapacity is usually close to size, so this is a win:
        //复制元素到新数组
        elementData = Arrays.copyOf (elementData, newCapacity);
    }

    //扩展到最大(某些虚拟机不需要存储头信息就可以扩容到 Integer.MAX_VALUE)
    private static int hugeCapacity (int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError ();
        return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
    }

获得size

size ()

 /**
     * Returns the number of elements in this list.
     * 返回集合中的元素个数
     * @return the number of elements in this list
     * 获得size
     */
    public int size () {
        return size;
    }

判断集合是否为空

isEmpty ()

  /**
     * Returns <tt>true</tt> if this list contains no elements.
     *
     * @return <tt>true</tt> if this list contains no elements
     * 是否为空
     */
    public boolean isEmpty () {
        return size == 0;
    }

判断集合中是否包含某个元素

contains (Object o)

 /**
     * Returns <tt>true</tt> if this list contains the specified element.
     * More formally, returns <tt>true</tt> if and only if this list contains
     * at least one element <tt>e</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
     *
     * @param o
     *         element whose presence in this list is to be tested
     *
     * @return <tt>true</tt> if this list contains the specified element
     * 是否含有o
     */
    public boolean contains (Object o) {
        return indexOf (o) >= 0;
    }

获得元素在集合中的索引

indexOf (Object o)

lastIndexOf (Object o)

   /**
     * Returns the index of the first occurrence of the specified element
     * in this list,
     * 返回指定元素在list中的第一个匹配项的索引
     * or -1 if this list does not contain the element.
     * 如果list中没有该元素则返回-1
     * More formally, returns the lowest index <tt>i</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
     * or -1 if there is no such index.
     */
    public int indexOf (Object o) {
        //如果o是空
        if (o == null) {
            for (int i = 0; i < size; i++)
                //返回第一个为空的位置
                if (elementData[i] == null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                //返回元素所在位置
                if (o.equals (elementData[i]))
                    return i;
        }
        //找不到该元素
        return - 1;
    }

    /**
     * Returns the index of the last occurrence of the specified element
     * 返回指定元素在list中的最后一个匹配项的索引
     * in this list, or -1 if this list does not contain the element.
     * 如果list中没有该元素则返回-1
     * More formally, returns the highest index <tt>i</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
     * or -1 if there is no such index.
     */
    public int lastIndexOf (Object o) {
        if (o == null) {
            for (int i = size - 1; i >= 0; i--)
                if (elementData[i] == null)
                    return i;
        } else {
            //从后往前遍历
            for (int i = size - 1; i >= 0; i--)
                if (o.equals (elementData[i]))
                    return i;
        }
        return - 1;
    }

浅拷贝

clone ()

 /**
     * Returns a shallow copy of this <tt>ArrayList</tt> instance.
     * 返回该实例的浅拷贝
     * (The elements themselves are not copied.)
     * 浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
     *
     * @return a clone of this <tt>ArrayList</tt> instance
     */
    public Object clone () {
        try {
            ArrayList<?> v = (ArrayList<?>) super.clone ();
            v.elementData = Arrays.copyOf (elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError (e);
        }
    }

返回包含所有元素de数组

Object[] toArray ()

< T > T[] toArray (T[] a)

  /**
     * Returns an array containing all of the elements in this list
     * 按顺序返回一个包含所有元素的数组
     * in proper sequence (from first to last element).
     * <p>The returned array will be "safe" in that no references to it are
     * maintained by this list.
     * 返回的数组将是“安全的”,因为此列表不维护对它的引用。
     * (In other words, this method must allocate
     * a new array).
     * The caller is thus free to modify the returned array.
     * 因此,方法调用者可以自由修改返回的数组。
     * <p>This method acts as bridge between array-based and collection-based
     * APIs.
     *
     * @return an array containing all of the elements in this list in
     * proper sequence
     */
    public Object[] toArray () {
        return Arrays.copyOf (elementData, size);
    }

    /**
     * Returns an array containing all of the elements in this list in proper
     * sequence (from first to last element); the runtime type of the returned
     * array is that of the specified array.
     * 返回的数组的运行时类型是指定数组的运行时类型
     * If the list fits in the
     * specified array, it is returned therein.  Otherwise, a new array is
     * allocated with the runtime type of the specified array and the size of
     * this list.
     * 如果列表和指定的数组大小一致,并且有剩余空间
     * <p>If the list fits in the specified array with room to spare
     * (i.e., the array has more elements than the list), the element in
     * the array immediately following the end of the collection is set to
     * <tt>null</tt>.
     * 紧跟在集合末尾的数组中的元素设置为null
     * (This is useful in determining the length of the
     * list <i>only</i> if the caller knows that the list does not contain
     * any null elements.)
     * 如果调用者知道该list里面没有包含有null,可以用这个来计算list的长度
     *
     * @param a
     *         the array into which the elements of the list are to
     *         be stored, if it is big enough; otherwise, a new array of the
     *         same runtime type is allocated for this purpose.
     *
     * @return an array containing the elements of the list
     *
     * @throws ArrayStoreException
     *         if the runtime type of the specified array
     *         is not a supertype of the runtime type of every element in
     *         this list
     * @throws NullPointerException
     *         if the specified array is null
     */
    @SuppressWarnings ("unchecked")
    public <T> T[] toArray (T[] a) {
        if (a.length < size)
            // Make a new array of a's runtime type, but my contents:
            //创建一个新数组存放
            return (T[]) Arrays.copyOf (elementData, size, a.getClass ());
        //不会产生新的数组对象
        System.arraycopy (elementData, 0, a, 0, size);
        //List的size的位置,把其设为null
        if (a.length > size)
            a[size] = null;
        return a;
    }

获得元素

get (int index)

 /**
     * Returns the element at the specified position in this list.
     * 获得对应位置的元素
     *
     * @param index
     *         index of the element to return
     *
     * @return the element at the specified position in this list
     *
     * @throws IndexOutOfBoundsException
     *         {@inheritDoc}
     */
    public E get (int index) {
        rangeCheck (index);

        return elementData (index);
    }

替换元素

set (int index, E element)

 /**
     * Replaces the element at the specified position in this list with
     * the specified element.
     * 替换对应位置的元素,并返回旧的元素
     * @param index
     *         index of the element to replace
     * @param element
     *         element to be stored at the specified position
     *
     * @return the element previously at the specified position
     *
     * @throws IndexOutOfBoundsException
     *         {@inheritDoc}
     */
    public E set (int index, E element) {
        rangeCheck (index);

        E oldValue = elementData (index);
        elementData[index] = element;
        return oldValue;
    }

增加元素

add (E e)

add (int index, E element)

 /**
     * Appends the specified element to the end of this list.
     *追加新元素在list的末尾
     * @param e
     *         element to be appended to this list
     *
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add (E e) {
        ensureCapacityInternal (size + 1);  // Increments modCount!!
        //先执行size++在赋值元素
        // 会有线程安全问题,当多个线程同时进入该方法
        elementData[size++] = e;
        return true;
    }

    /**
     * Inserts the specified element at the specified position in this
     * list.
     * 在指定位置添加元素
     * Shifts the element currently at that position (if any) and
     * any subsequent elements to the right (adds one to their indices).
     * 将当前位于该位置的元素(如果有)和所有后续元素向右移动(将其索引加1)
     * @param index
     *         index at which the specified element is to be inserted
     * @param element
     *         element to be inserted
     *
     * @throws IndexOutOfBoundsException
     *         {@inheritDoc}
     */
    public void add (int index, E element) {
        //检查index的范围
        rangeCheckForAdd (index);

        //确认是否需要扩容并进行扩容
        ensureCapacityInternal (size + 1);  // Increments modCount!!
        //把index之后的元素都后移一位
        System.arraycopy (elementData, index, elementData, index + 1,
                size - index);
        //在index位置加入新元素
        elementData[index] = element;
        size++;
    }

  
    /**
     * Appends all of the elements in the specified collection to the end of
     * this list, in the order that they are returned by the
     * specified collection's Iterator.
     * 在列表尾部顺序追加所有元素
     * The behavior of this operation is
     * undefined if the specified collection is modified while the operation
     * is in progress.
     * 如果在该操作进行时collection被修改了,会使得该行为具有不确定性
     * (This implies that the behavior of this call is
     * undefined if the specified collection is this list, and this
     * list is nonempty.)
     *
     * @param c
     *         collection containing elements to be added to this list
     *
     * @return <tt>true</tt> if this list changed as a result of the call
     *
     * @throws NullPointerException
     *         if the specified collection is null
     */
    public boolean addAll (Collection<? extends E> c) {
        Object[] a = c.toArray ();
        int numNew = a.length;
        ensureCapacityInternal (size + numNew);  // Increments modCount
        System.arraycopy (a, 0, elementData, size, numNew);
        size += numNew;
        //c有元素则true没有false
        return numNew != 0;
    }

    /**
     * Inserts all of the elements in the specified collection into this
     * list, starting at the specified position.
     * 从指定位置开始顺序追加元素
     * Shifts the element
     * currently at that position (if any) and any subsequent elements to
     * the right (increases their indices).
     * 将当前位于该位置的元素(如果有)和所有后续元素向右移动(将其索引加1)
     * The new elements will appear
     * in the list in the order that they are returned by the
     * specified collection's iterator.
     *
     * @param index
     *         index at which to insert the first element from the
     *         specified collection
     * @param c
     *         collection containing elements to be added to this list
     *
     * @return <tt>true</tt> if this list changed as a result of the call
     *
     * @throws IndexOutOfBoundsException
     *         {@inheritDoc}
     * @throws NullPointerException
     *         if the specified collection is null
     */
    public boolean addAll (int index, Collection<? extends E> c) {
        rangeCheckForAdd (index);

        Object[] a = c.toArray ();
        int numNew = a.length;
        ensureCapacityInternal (size + numNew);  // Increments modCount

        int numMoved = size - index;
        if (numMoved > 0)
            //原来元素后移numMoved位
            System.arraycopy (elementData, index, elementData, index + numNew,
                    numMoved);

        //新元素放置
        System.arraycopy (a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }

移除元素

remove (int index)

remove (Object o)

fastRemove (int index)

clear ()

removeAll (Collection<?> c)

removeRange (int fromIndex, int toIndex)

retainAll (Collection<?> c)

batchRemove (Collection<?> c, boolean complement)

  /**
     * Removes the element at the specified position in this list.
     * 移除指定位置的元素,并返回该元素
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).
     * 将当前位于该位置所有后续元素向左移动(索引减1)
     * @param index
     *         the index of the element to be removed
     *
     * @return the element that was removed from the list
     *
     * @throws IndexOutOfBoundsException
     *         {@inheritDoc}
     */
    public E remove (int index) {
        //检查索引是否在范围内
        rangeCheck (index);

        //结构上的改变
        modCount++;
        E oldValue = elementData (index);

        //numMoved用来判断是否需要移动元素
        int numMoved = size - index - 1;
        //需要移动
        if (numMoved > 0)
            //index之后的元素都前移一位
            System.arraycopy (elementData, index + 1, elementData, index,
                    numMoved);
        //不需要移动(index的元素是最后一位)
        //把最后一位的元素设为null(让GC回收)然后size减一
        elementData[-- size] = null; // clear to let GC do its work

        return oldValue;
    }

    /**
     * Removes the first occurrence of the specified element from this list,
     * if it is present.
     * 如果存在o元素,移除list中第一次遇到的那个元素,就是靠前的那个
     * If the list does not contain the element, it is
     * unchanged.
     * 如果不存在o元素,则列表不变
     * More formally, removes the element with the lowest index
     * 更正式地说,移除index最小的那个元素
     * <tt>i</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
     * (if such an element exists).  Returns <tt>true</tt> if this list
     * contained the specified element (or equivalently, if this list
     * changed as a result of the call).
     * 如果list中有该元素,则返回true
     * @param o
     *         element to be removed from this list, if present
     *
     * @return <tt>true</tt> if this list contained the specified element
     */
    public boolean remove (Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove (index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals (elementData[index])) {
                    fastRemove (index);
                    return true;
                }
        }
        return false;
    }

    /*
     * Private remove method that skips bounds checking and does not
     * return the value removed.
     * 不进行检查且不返回元素的remove
     */
    private void fastRemove (int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy (elementData, index + 1, elementData, index,
                    numMoved);
        elementData[-- size] = null; // clear to let GC do its work
    }

    /**
     * Removes all of the elements from this list.
     * The list will
     * be empty after this call returns.
     * 移除列表中的所有元素
     */
    public void clear () {
        modCount++;

        // clear to let GC do its work
        for (int i = 0; i < size; i++)
            elementData[i] = null;

        size = 0;
    }

 	/**
     * Removes from this list all of its elements that are contained in the
     * specified collection.
     * 移除列表中包含的collection中指定的所有元素
     *
     * @param c
     *         collection containing elements to be removed from this list
     *
     * @return {@code true} if this list changed as a result of the call
     *
     * @throws ClassCastException
     *         if the class of an element of this list
     *         is incompatible with the specified collection
     *         (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException
     *         if this list contains a null element and the
     *         specified collection does not permit null elements
     *         (<a href="Collection.html#optional-restrictions">optional</a>),
     *         or if the specified collection is null
     * @see Collection#contains(Object)
     */
    public boolean removeAll (Collection<?> c) {
        //NullPointerException
        Objects.requireNonNull (c);
        return batchRemove (c, false);
    }


    /**
     * Removes from this list all of the elements whose index is between
     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
     * 移除fromIndex到toIndex之间的元素
     * Shifts any succeeding elements to the left (reduces their index).
     * 移动后续元素到左边,减少索引值
     * This call shortens the list by {@code (toIndex - fromIndex)} elements.
     * (If {@code toIndex==fromIndex}, this operation has no effect.)
     *
     * @throws IndexOutOfBoundsException
     *         if {@code fromIndex} or
     *         {@code toIndex} is out of range
     *         ({@code fromIndex < 0 ||
     *         fromIndex >= size() ||
     *         toIndex > size() ||
     *         toIndex < fromIndex})
     */
    protected void removeRange (int fromIndex, int toIndex) {
        modCount++;
        int numMoved = size - toIndex;
        //移动后续元素到左边
        System.arraycopy (elementData, toIndex, elementData, fromIndex,
                numMoved);

        // clear to let GC do its work
        // 成功删除了toIndex - fromIndex元素,将后面空间置空
        int newSize = size - (toIndex - fromIndex);
        for (int i = newSize; i < size; i++) {
            elementData[i] = null;
        }
        size = newSize;
    }

  /**
     * Retains only the elements in this list that are contained in the
     * specified collection.  In other words, removes from this list all
     * of its elements that are not contained in the specified collection.
     * 仅保留集合中collection包含的元素,也即是说,移除collection中不包含的元素
     * @param c
     *         collection containing elements to be retained in this list
     *
     * @return {@code true} if this list changed as a result of the call
     *
     * @throws ClassCastException
     *         if the class of an element of this list
     *         is incompatible with the specified collection
     *         (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException
     *         if this list contains a null element and the
     *         specified collection does not permit null elements
     *         (<a href="Collection.html#optional-restrictions">optional</a>),
     *         or if the specified collection is null
     * @see Collection#contains(Object)
     */
    public boolean retainAll (Collection<?> c) {
        Objects.requireNonNull (c);
        return batchRemove (c, true);
    }

    /**
     * 批量移除
     * @param c
     * @param complement
     * @return
     */
    private boolean batchRemove (Collection<?> c, boolean complement) {
        final Object[] elementData = this.elementData;
        int r = 0, w = 0;
        //list是否有修改的标志
        boolean modified = false;
        try {
            //遍历列表,判断每一个元素是否在collection中
            //complement==false,list中不包含collection指定位置的数据时,就将list的r位置的数据覆盖掉w位置的数据,
            //complement==true,list中包含collection指定位置的数据时,就将list的r位置的数据覆盖掉w位置的数据,
            // r位置的数据不变,并其w自增,r自增。
            // 否则,r自增,w不自增
            //即把不需要移除的元素前移覆盖掉需要移除的元素
            for (; r < size; r++)
                if (c.contains (elementData[r]) == complement)
                    elementData[w++] = elementData[r];
        } finally {
            // Preserve behavioral compatibility with AbstractCollection,
            // even if c.contains() throws.
            //c.contains()可能抛出异常,要保持与AbstractCollection的行为兼容性,
            //r!=size则上面修改都r位置时发生了异常
            //把r后续的元素原样前移
            if (r != size) {
                System.arraycopy (elementData, r,
                        elementData, w,
                        size - r);
                w += size - r;
            }
            // 成功删除了元素,将后面空间置空
            if (w != size) {
                // clear to let GC do its work
                for (int i = w; i < size; i++)
                    elementData[i] = null;
                modCount += size - w;
                size = w;
                modified = true;
            }
        }
        return modified;
    }


范围检查

rangeCheck (int index)

rangeCheckForAdd (int index)

outOfBoundsMsg (int index)

    /**
     * Checks if the given index is in range.  If not, throws an appropriate
     * runtime exception.  This method does *not* check if the index is
     * negative: It is always used immediately prior to an array access,
     * which throws an ArrayIndexOutOfBoundsException if index is negative.
     * 检查index是否超出范围
     */
    private void rangeCheck (int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException (outOfBoundsMsg (index));
    }

    /**
     * A version of rangeCheck used by add and addAll.
     * 检查index是否超出范围
     */
    private void rangeCheckForAdd (int index) {
        //是否够加一个元素
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException (outOfBoundsMsg (index));
    }

    /**
     * Constructs an IndexOutOfBoundsException detail message.
     * 构造IndexOutOfBoundsException详细信息
     *
     * Of the many possible refactorings of the error handling code,
     * this "outlining" performs best with both server and client VMs.
     */
    private String outOfBoundsMsg (int index) {
        return "Index: " + index + ", Size: " + size;
    }

序列化与反序列化

writeObject (java.io.ObjectOutputStream s)

readObject (java.io.ObjectInputStream s)

    /**
     * Save the state of the <tt>ArrayList</tt> instance to a stream (that
     * is, serialize it).
     * 把arrayList的状态保存在stream中,也即是序列化
     *
     */
    private void writeObject (java.io.ObjectOutputStream s)
            throws java.io.IOException {
        // Write out element count, and any hidden stuff
        int expectedModCount = modCount;
        s.defaultWriteObject ();

        // Write out size as capacity for behavioural compatibility with clone()
        //把size写出,当做clone()方法的容量
        s.writeInt (size);

        // Write out all elements in the proper order.
        //按顺序写出所有元素
        for (int i = 0; i < size; i++) {
            s.writeObject (elementData[i]);
        }

        //确保写出过程没有集合被修改,否则报异常
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException ();
        }
    }

    /**
     * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
     * deserialize it).
     * 从stream中重建arrayList,也即是反序列化
     */
    private void readObject (java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
        elementData = EMPTY_ELEMENTDATA;

        // Read in size, and any hidden stuff
        s.defaultReadObject ();

        // Read in capacity
        //读取size
        s.readInt (); // ignored

        if (size > 0) {
            // be like clone(), allocate array based upon size not capacity
            //与clone()类似,根据大小而不是容量分配数组,如果size大于默认容量则(10)capacity=size,否则capacity=10
            int capacity = calculateCapacity (elementData, size);
            SharedSecrets.getJavaOISAccess ().checkArray (s, Object[].class, capacity);
            ensureCapacityInternal (size);

            Object[] a = elementData;
            // Read in all elements in the proper order.
            for (int i = 0; i < size; i++) {
                a[i] = s.readObject ();
            }
        }
    }

listIterator (int index)

listIterator ()

iterator ()

  /**
     * Returns a list iterator over the elements in this list (in proper
     * sequence), starting at the specified position in the list.
     * 从指定位置开始顺序返回一个ListIterator
     *
     * The specified index indicates the first element that would be
     * returned by an initial call to {@link ListIterator#next next}.
     * 指定的索引暗示着第一次调用 {@link ListIterator#next next}将返回的第一个元素。
     *
     * An initial call to {@link ListIterator#previous previous} would
     * return the element with the specified index minus one.
     * 第一次调用 {@link ListIterator#previous previous}将返回的index-1个元素
     *
     * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
     *
     * @throws IndexOutOfBoundsException
     *         {@inheritDoc}
     */
    public ListIterator<E> listIterator (int index) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException ("Index: " + index);
        //创建一个listStr对象(具体看ListItr类注释)
        return new ListItr (index);
    }

    /**
     * Returns a list iterator over the elements in this list (in proper
     * sequence).
     * 返回一个包含list中所有元素的ListIterator
     * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
     *
     * @see #listIterator(int)
     */
    public ListIterator<E> listIterator () {
        return new ListItr (0);
    }

    /**
     * Returns an iterator over the elements in this list in proper sequence.
     * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
     * 返回一个包含list中所有元素的Iterator
     * @return an iterator over the elements in this list in proper sequence
     */
    public Iterator<E> iterator () {
        return new Itr ();
    }

Iterator类

属性

/**
     * An optimized version of AbstractList.Itr
     * AbstractList.Itr的优化版本
     */
    private class Itr implements Iterator<E> {
        //游标: 下一个要返回的元素的索引
        int cursor;       // index of next element to return
        //返回的最后一个元素的索引(相当于当前遍历的元素的位置), 没有就返回-1
        int lastRet = - 1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

hasNext ()

  /**
         * 判断是否还有下一个元素
         * @return
         */
        public boolean hasNext () {
            return cursor != size;
        }

next ()

  /**
         * 获取下一个元素
         * @return
         */
        @SuppressWarnings ("unchecked")
        public E next () {
            //检查遍历过程中是否被修改过
            checkForComodification ();
            //记录索引位置
            int i = cursor;
            //如果获取元素的位置大于集合元素个数,则抛出异常
            if (i >= size)
                throw new NoSuchElementException ();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException ();
            //游标后移
            cursor = i + 1;
            //lastRet记录刚刚返回的位置且返回cursor处元素
            return (E) elementData[lastRet = i];
        }

remove ()

  /**
         * 移除最后一元素
         */
        public void remove () {
            //没有指向的元素
            if (lastRet < 0)
                throw new IllegalStateException ();
            checkForComodification ();

            try {
                //移除所指向的元素
                ArrayList.this.remove (lastRet);
                //把游标指向被移除的位置,相当于现在下一个元素的位置
                cursor = lastRet;
                //当前没有指向的元素(设为-1)
                lastRet = - 1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException ();
            }
        }

forEachRemaining (Consumer<? super E> consumer)

  /**
         * 遍历剩下的元素,只能用一次
         * @param consumer
         */
        @Override
        @SuppressWarnings ("unchecked")
        public void forEachRemaining (Consumer<? super E> consumer) {
            //consumer不为空
            Objects.requireNonNull (consumer);
            final int size = ArrayList.this.size;
            //记录索引位置
            int i = cursor;
            if (i >= size) {
                return;
            }
            final Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length) {
                throw new ConcurrentModificationException ();
            }
            while (i != size && modCount == expectedModCount) {
                consumer.accept ((E) elementData[i++]);
            }
            // update once at end of iteration to reduce heap write traffic
            //在迭代结束时才更新,以减少堆写入
            cursor = i;
            lastRet = i - 1;
            checkForComodification ();
        }

checkForComodification ()

  /**
         * 检查是否被修改过
         */
        final void checkForComodification () {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException ();
        }
    }

ListItr

    /**
     * An optimized version of AbstractList.ListItr
     * AbstractList.ListItr优化版
     */
    private class ListItr extends Itr implements ListIterator<E> {
        ListItr (int index) {
            super ();
            //cursor是当前元素的位置
            cursor = index;
        }

        //是否有前驱(cursor==0代表当前之前第一个位置,所以没有前驱)
        public boolean hasPrevious () {
            return cursor != 0;
        }

        //下一个位置
        public int nextIndex () {
            return cursor;
        }

        //上一个位置
        public int previousIndex () {
            return cursor - 1;
        }

        /**
         * 返回上一个位置的元素
         * @return
         */
        @SuppressWarnings ("unchecked")
        public E previous () {
            checkForComodification ();
            //记录上一个元素的位置
            int i = cursor - 1;
            if (i < 0)
                throw new NoSuchElementException ();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException ();
            //重置cursor为当前元素的位置
            cursor = i;
            return (E) elementData[lastRet = i];
        }

        //把当前位置的值重置为e元素
        public void set (E e) {
            if (lastRet < 0)
                throw new IllegalStateException ();
            checkForComodification ();

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

        //在遍历的当前位置插入e
        public void add (E e) {
            checkForComodification ();

            try {
                int i = cursor;
                ArrayList.this.add (i, e);
                cursor = i + 1;
                lastRet = - 1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException ();
            }
        }
    }

    /**
     * Returns a view of the portion of this list between the specified
     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.  (If
     * {@code fromIndex} and {@code toIndex} are equal, the returned list is
     * empty.)
     * 返回从fromIndex到toIndex之间的list
     *
     * The returned list is backed by this list, so non-structural
     * changes in the returned list are reflected in this list, and vice-versa.
     * The returned list supports all of the optional list operations.
     * <p>This method eliminates the need for explicit range operations (of
     * the sort that commonly exist for arrays).  Any operation that expects
     * a list can be used as a range operation by passing a subList view
     * instead of a whole list.  For example, the following idiom
     * removes a range of elements from a list:
     * <pre>
     *      list.subList(from, to).clear();
     * </pre>
     * Similar idioms may be constructed for {@link #indexOf(Object)} and
     * {@link #lastIndexOf(Object)}, and all of the algorithms in the
     * {@link Collections} class can be applied to a subList.
     * <p>The semantics of the list returned by this method become undefined if
     * the backing list (i.e., this list) is <i>structurally modified</i> in
     * any way other than via the returned list.  (Structural modifications are
     * those that change the size of this list, or otherwise perturb it in such
     * a fashion that iterations in progress may yield incorrect results.)
     *
     * @throws IndexOutOfBoundsException
     *         {@inheritDoc}
     * @throws IllegalArgumentException
     *         {@inheritDoc}
     */
    public List<E> subList (int fromIndex, int toIndex) {
        subListRangeCheck (fromIndex, toIndex, size);
        return new SubList (this, 0, fromIndex, toIndex);
    }

    /**
     * 检查range合法性
     * @param fromIndex
     * @param toIndex
     * @param size
     */
    static void subListRangeCheck (int fromIndex, int toIndex, int size) {
        if (fromIndex < 0)
            throw new IndexOutOfBoundsException ("fromIndex = " + fromIndex);
        if (toIndex > size)
            throw new IndexOutOfBoundsException ("toIndex = " + toIndex);
        if (fromIndex > toIndex)
            throw new IllegalArgumentException ("fromIndex(" + fromIndex +
                    ") > toIndex(" + toIndex + ")");
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值