ArrayList的源码实现

List是大家在开发过程中用到的比较多的集合,其jdk源码实现如下,以主要方法分析。
例子


            List<String> list = new ArrayList<>();
//           add(E e)
            list.add("1");
            list.add("2");
            list.add("3");
            System.out.println("-----------------------result-----------------------");
            System.out.println(list);//[1, 2, 3]
            System.out.println("-----------------------result-----------------------");

//           void add(int index, E element)
            list.add(1,"4");
            System.out.println("-----------------------result-----------------------");
            System.out.println(list);//[1, 4, 2, 3]
            System.out.println("-----------------------result-----------------------");

//          addAll(Collection<? extends E> c)
            List<String> lt = new ArrayList<>();
            lt.add("4");
            lt.add("5");
            list.addAll(lt);
            System.out.println("-----------------------result-----------------------");
            System.out.println(list);//[1, 4, 2, 3, 4, 5]
            System.out.println("-----------------------result-----------------------");

//            addAll(int index, Collection<? extends E> c)
            list.addAll(4,lt);
            System.out.println("-----------------------result-----------------------");
            System.out.println(list);//[1, 4, 2, 3, 4, 5, 4, 5]
            System.out.println("-----------------------result-----------------------");

//            remove(int index);
            list.remove(1);
            System.out.println("-----------------------result-----------------------");
            System.out.println(list);//[1, 2, 3, 4, 5, 4, 5]
            System.out.println("-----------------------result-----------------------");
//            remove(Object o);
            List<User> listUsers = new ArrayList<>();
            User user1 = new User("小小");
            User user2 = new User("塔基哥");
            listUsers.add(user1);
            listUsers.add(user2);

            listUsers.remove(user1);
            System.out.println("-----------------------result-----------------------");
            System.out.println(listUsers+">>>>>>>>"+listUsers.get(0).getName());//[com.java.test.User@4f801c4]>>>>>>>>塔基哥
            System.out.println("-----------------------result-----------------------");

//            T[] toArray(T[] a)
            System.out.println("-----------------------result-----------------------");
            String[] num_ary = list.toArray(new String[]{});
            StringBuffer sf = new StringBuffer();
            for(String num_str:num_ary){
                if("".equals(sf.toString()))
                    sf.append(num_str);
                else
                    sf.append(","+num_str);
            }
            System.out.println(list.toArray(num_ary)+">>>>>>>>["+sf.toString()+"]");//[Ljava.lang.String;@61bf61a0>>>>>>>>[1,2,3,4,5,4,5]
            System.out.println("-----------------------result-----------------------");

//            contains(Object o);
            System.out.println("-----------------------result-----------------------");
            System.out.println(listUsers.contains(user2));//true
            System.out.println("-----------------------result-----------------------");


//            containsAll(Collection<?> c);
            List<User> listUsersTemp = new ArrayList<>();
            listUsersTemp.add(user2);
            System.out.println("-----------------------result-----------------------");
            System.out.println(listUsers.containsAll(listUsersTemp));//true
            System.out.println("-----------------------result-----------------------");
//            subList(int fromIndex, int toIndex)
            List<String> listSubList = new ArrayList<>(list.subList(1,3));
            System.out.println("-----------------------result-----------------------");
            System.out.println(listSubList);//[2, 3]
            System.out.println("-----------------------result-----------------------");

//            equals(Object o);

            List<String> listEqs = new ArrayList<>();
            listEqs.add("111");
            List<String> listEqst = new ArrayList<>();
            listEqst.add("111");
            System.out.println("-----------------------result-----------------------");
            System.out.println(listEqs.equals(listEqst));//true
            System.out.println("-----------------------result-----------------------");

//          e  remove(int index);

            System.out.println("-----------------------result-----------------------");
            System.out.println("list.get(2)>>>>>>"+list.get(2));
            String remove = list.remove(2);
            System.out.println(remove);
            System.out.println("-----------------------result-----------------------");


//            void clear();
            System.out.println("-----------------------result-----------------------");
            list.clear();
            System.out.println(list.size());
            System.out.println("-----------------------result-----------------------");


            //大坑    subList
            //--------------------------------subList--------------------------------


            List<String> data = new ArrayList<>();
            data.add("one");
            data.add("two");
            data.add("three");
            data.add("four");
            data.add("five");
            List<String> listSubListTest = data.subList(2,4);
            System.out.println("-----------------------result-----------------------");
            System.out.println("-----------before-----------");
            System.out.println("data>>>"+data);//data>>>[one, two, three, four, five]
            System.out.println("listSubListTest>>>"+listSubListTest);//listSubListTest>>>[three, four]

            System.out.println("-----------after-----------");
            //神奇的事情发生了
            listSubListTest.add("six");
            System.out.println("data>>>"+data);//data>>>[one, two, three, four, six, five]
            System.out.println("listSubListTest>>>"+listSubListTest);//listSubListTest>>>[three, four, six]
            System.out.println("-----------------------result-----------------------");

            //--------------------------------subList--------------------------------

这是ArrayList的源码里声明的几个变量

 /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;

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

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to
     * DEFAULT_CAPACITY when the first element is added.
     */
    private transient Object[] elementData;

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

1、add(E e)

            List<String> list = new ArrayList<>();

//           add(E e)
            list.add("1");
            list.add("2");
            list.add("3");
            System.out.println("-----------------------result-----------------------");
            System.out.println(list);//[1, 2, 3]
            System.out.println("-----------------------result-----------------------");

具体实现如下

    /**
     * Appends the specified element to the end of this 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!!
        elementData[size++] = e;
        return true;
    }
   /**
     * A version of rangeCheck used by add and addAll.
     */
    private void rangeCheckForAdd(int index) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
        private void ensureCapacityInternal(int minCapacity) {
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

    private void ensureExplicitCapacity(int minCapacity) {
        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.
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     */
    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;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
       /**
     * Copies the specified array, truncating or padding with nulls (if necessary)
     * so the copy has the specified length.  For all indices that are
     * valid in both the original array and the copy, the two arrays will
     * contain identical values.  For any indices that are valid in the
     * copy but not the original, the copy will contain <tt>null</tt>.
     * Such indices will exist if and only if the specified length
     * is greater than that of the original array.
     * The resulting array is of exactly the same class as the original array.
     *
     * @param original the array to be copied
     * @param newLength the length of the copy to be returned
     * @return a copy of the original array, truncated or padded with nulls
     *     to obtain the specified length
     * @throws NegativeArraySizeException if <tt>newLength</tt> is negative
     * @throws NullPointerException if <tt>original</tt> is null
     * @since 1.6
     */
    public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }
        /**
     * Copies the specified array, truncating or padding with nulls (if necessary)
     * so the copy has the specified length.  For all indices that are
     * valid in both the original array and the copy, the two arrays will
     * contain identical values.  For any indices that are valid in the
     * copy but not the original, the copy will contain <tt>null</tt>.
     * Such indices will exist if and only if the specified length
     * is greater than that of the original array.
     * The resulting array is of the class <tt>newType</tt>.
     *
     * @param original the array to be copied
     * @param newLength the length of the copy to be returned
     * @param newType the class of the copy to be returned
     * @return a copy of the original array, truncated or padded with nulls
     *     to obtain the specified length
     * @throws NegativeArraySizeException if <tt>newLength</tt> is negative
     * @throws NullPointerException if <tt>original</tt> is null
     * @throws ArrayStoreException if an element copied from
     *     <tt>original</tt> is not of a runtime type that can be stored in
     *     an array of class <tt>newType</tt>
     * @since 1.6
     */
    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

2、oid add(int index, E element)

            list.add(1,"4");
            System.out.println("-----------------------result-----------------------");
            System.out.println(list);//[1, 4, 2, 3]
            System.out.println("-----------------------result-----------------------");

实现源码与add类似

    /**
     * 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).
     *
     * @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) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

3、addAll(Collection

            List<String> lt = new ArrayList<>();
            lt.add("4");
            lt.add("5");
            list.addAll(lt);
            System.out.println("-----------------------result-----------------------");
            System.out.println(list);//[1, 4, 2, 3, 4, 5]
            System.out.println("-----------------------result-----------------------");

实现源码

  /**
     * 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.  (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;
        return numNew != 0;
    }

4、 addAll(int index, Collection

            list.addAll(4,lt);
            System.out.println("-----------------------result-----------------------");
            System.out.println(list);//[1, 4, 2, 3, 4, 5, 4, 5]
            System.out.println("-----------------------result-----------------------");

实现源码

/**
     * 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).  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)
            System.arraycopy(elementData, index, elementData, index + numNew,
                             numMoved);

        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }

5、 remove(int index);

            list.remove(1);
            System.out.println("-----------------------result-----------------------");
            System.out.println(list);//[1, 2, 3, 4, 5, 4, 5]
            System.out.println("-----------------------result-----------------------");

源码实现

    /**
     * Removes the element at the specified position in this list.
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).
     *
     * @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);

        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

        return oldValue;
    }
        /**
     * 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.
     */
    private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    E elementData(int index) {
        return (E) elementData[index];
    }

6、 remove(Object o);

            List<User> listUsers = new ArrayList<>();
            User user1 = new User("小小");
            User user2 = new User("塔基哥");
            listUsers.add(user1);
            listUsers.add(user2);

            listUsers.remove(user1);
            System.out.println("-----------------------result-----------------------");
            System.out.println(listUsers+">>>>>>>>"+listUsers.get(0).getName());//[com.java.test.User@4f801c4]>>>>>>>>塔基哥
            System.out.println("-----------------------result-----------------------");

源码实现

    /**
     * Removes the first occurrence of the specified element from this list,
     * if it is present.  If the list does not contain the element, it is
     * unchanged.  More formally, removes the element with the lowest 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).
     *
     * @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.
     */
    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
    }

7、 T[] toArray(T[] a)

            System.out.println("-----------------------result-----------------------");
            String[] num_ary = list.toArray(new String[]{});
            StringBuffer sf = new StringBuffer();
            for(String num_str:num_ary){
                if("".equals(sf.toString()))
                    sf.append(num_str);
                else
                    sf.append(","+num_str);
            }
            System.out.println(list.toArray(num_ary)+">>>>>>>>["+sf.toString()+"]");//[Ljava.lang.String;@61bf61a0>>>>>>>>[1,2,3,4,5,4,5]
            System.out.println("-----------------------result-----------------------");

源码实现

/**
     * 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>.  (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.)
     *
     * @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)
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

8、 contains(Object o);

            System.out.println("-----------------------result-----------------------");
            System.out.println(listUsers.contains(user2));//true
            System.out.println("-----------------------result-----------------------");

源码实现

    /**
     * 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
     */
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }
        /**
     * Returns the index of the first occurrence of the specified element
     * in this list, or -1 if this list does not contain the element.
     * 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) {
        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;
    }

9、 containsAll(Collection

            List<User> listUsersTemp = new ArrayList<>();
            listUsersTemp.add(user2);
            System.out.println("-----------------------result-----------------------");
            System.out.println(listUsers.containsAll(listUsersTemp));//true
            System.out.println("-----------------------result-----------------------");

源码实现

    /**
     * {@inheritDoc}
     *
     * <p>This implementation iterates over the specified collection,
     * checking each element returned by the iterator in turn to see
     * if it's contained in this collection.  If all elements are so
     * contained <tt>true</tt> is returned, otherwise <tt>false</tt>.
     *
     * @throws ClassCastException            {@inheritDoc}
     * @throws NullPointerException          {@inheritDoc}
     * @see #contains(Object)
     */
    public boolean containsAll(Collection<?> c) {
        for (Object e : c)
            if (!contains(e))
                return false;
        return true;
    }

10、 subList(int fromIndex, int toIndex)
这个比较特殊 放在最后说

11、 e remove(int index);

            System.out.println("-----------------------result-----------------------");
            System.out.println("list.get(2)>>>>>>"+list.get(2));
            String remove = list.remove(2);
            System.out.println(remove);
            System.out.println("-----------------------result-----------------------");

源码

    /**
     * Removes the element at the specified position in this list.
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).
     *
     * @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);

        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

        return oldValue;
    }

12、 void clear()

            System.out.println("-----------------------result-----------------------");
            list.clear();
            System.out.println(list.size());
            System.out.println("-----------------------result-----------------------");

实现源码

    /**
     * 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;
    }

其实看了上面的代码可以发现ArrayList的操作基本上都是通过System.arraycopy()来实现的。

//src:源数组;  
//srcPos:源数组要复制的起始位置;
//dest:目的数组;    
//destPos:目的数组放置的起始位置;
//length:复制的长度。
System.arraycopy((Object src,int srcPos,Object dest,int destPos,int length)

现在重点来说subList 为什么会出现我的的测试例子里面的那一幕,为什么我需要在使用subList方法后要重新包装?

 List<String> listSubList = new ArrayList<>(list.subList(1,3));

为什么不包装的请开心 操作截取后的list对象会影响原来的list对象?

            List<String> data = new ArrayList<>();
            data.add("one");
            data.add("two");
            data.add("three");
            data.add("four");
            data.add("five");
            List<String> listSubListTest = data.subList(2,4);
            System.out.println("-----------------------result-----------------------");
            System.out.println("-----------before-----------");
            System.out.println("data>>>"+data);//data>>>[one, two, three, four, five]
            System.out.println("listSubListTest>>>"+listSubListTest);//listSubListTest>>>[three, four]

            System.out.println("-----------after-----------");
            //神奇的事情发生了
            listSubListTest.add("six");
            System.out.println("data>>>"+data);//data>>>[one, two, three, four, six, five]
            System.out.println("listSubListTest>>>"+listSubListTest);//listSubListTest>>>[three, four, six]
            System.out.println("-----------------------result-----------------------");

说明:
这是因为subList方法的实现时把当前对象的引用传入了实现方法
subList传入了this
return new SubList(this, 0, fromIndex, toIndex);
这样截取后的对象的引用是截取之前的原list对象。这样的话list对象就有了两个引用,操作任何一个就能影响list对象。
这也是为什么在使用subList方法后需要重新包装的原因重新包装就会产生一个新的对象这样操作,不会影响原对象。

 /**
     * 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.)  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);
    }

 private class SubList extends AbstractList<E> implements RandomAccess {
        private final AbstractList<E> parent;
        private final int parentOffset;
        private final int offset;
        int size;

        SubList(AbstractList<E> parent,
                int offset, int fromIndex, int toIndex) {
            this.parent = parent;
            this.parentOffset = fromIndex;
            this.offset = offset + fromIndex;
            this.size = toIndex - fromIndex;
            this.modCount = ArrayList.this.modCount;
        }

        public E set(int index, E e) {
            rangeCheck(index);
            checkForComodification();
            E oldValue = ArrayList.this.elementData(offset + index);
            ArrayList.this.elementData[offset + index] = e;
            return oldValue;
        }

        public E get(int index) {
            rangeCheck(index);
            checkForComodification();
            return ArrayList.this.elementData(offset + index);
        }

        public int size() {
            checkForComodification();
            return this.size;
        }

        public void add(int index, E e) {
            rangeCheckForAdd(index);
            checkForComodification();
            parent.add(parentOffset + index, e);
            this.modCount = parent.modCount;
            this.size++;
        }

        public E remove(int index) {
            rangeCheck(index);
            checkForComodification();
            E result = parent.remove(parentOffset + index);
            this.modCount = parent.modCount;
            this.size--;
            return result;
        }

        protected void removeRange(int fromIndex, int toIndex) {
            checkForComodification();
            parent.removeRange(parentOffset + fromIndex,
                               parentOffset + toIndex);
            this.modCount = parent.modCount;
            this.size -= toIndex - fromIndex;
        }

        public boolean addAll(Collection<? extends E> c) {
            return addAll(this.size, c);
        }

        public boolean addAll(int index, Collection<? extends E> c) {
            rangeCheckForAdd(index);
            int cSize = c.size();
            if (cSize==0)
                return false;

            checkForComodification();
            parent.addAll(parentOffset + index, c);
            this.modCount = parent.modCount;
            this.size += cSize;
            return true;
        }

        public Iterator<E> iterator() {
            return listIterator();
        }

        public ListIterator<E> listIterator(final int index) {
            checkForComodification();
            rangeCheckForAdd(index);
            final int offset = this.offset;

            return new ListIterator<E>() {
                int cursor = index;
                int lastRet = -1;
                int expectedModCount = ArrayList.this.modCount;

                public boolean hasNext() {
                    return cursor != SubList.this.size;
                }

                @SuppressWarnings("unchecked")
                public E next() {
                    checkForComodification();
                    int i = cursor;
                    if (i >= SubList.this.size)
                        throw new NoSuchElementException();
                    Object[] elementData = ArrayList.this.elementData;
                    if (offset + i >= elementData.length)
                        throw new ConcurrentModificationException();
                    cursor = i + 1;
                    return (E) elementData[offset + (lastRet = i)];
                }

                public boolean hasPrevious() {
                    return cursor != 0;
                }

                @SuppressWarnings("unchecked")
                public E previous() {
                    checkForComodification();
                    int i = cursor - 1;
                    if (i < 0)
                        throw new NoSuchElementException();
                    Object[] elementData = ArrayList.this.elementData;
                    if (offset + i >= elementData.length)
                        throw new ConcurrentModificationException();
                    cursor = i;
                    return (E) elementData[offset + (lastRet = i)];
                }

                public int nextIndex() {
                    return cursor;
                }

                public int previousIndex() {
                    return cursor - 1;
                }

                public void remove() {
                    if (lastRet < 0)
                        throw new IllegalStateException();
                    checkForComodification();

                    try {
                        SubList.this.remove(lastRet);
                        cursor = lastRet;
                        lastRet = -1;
                        expectedModCount = ArrayList.this.modCount;
                    } catch (IndexOutOfBoundsException ex) {
                        throw new ConcurrentModificationException();
                    }
                }

                public void set(E e) {
                    if (lastRet < 0)
                        throw new IllegalStateException();
                    checkForComodification();

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

                public void add(E e) {
                    checkForComodification();

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

                final void checkForComodification() {
                    if (expectedModCount != ArrayList.this.modCount)
                        throw new ConcurrentModificationException();
                }
            };
        }

        public List<E> subList(int fromIndex, int toIndex) {
            subListRangeCheck(fromIndex, toIndex, size);
            return new SubList(this, offset, fromIndex, toIndex);
        }

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

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

        private String outOfBoundsMsg(int index) {
            return "Index: "+index+", Size: "+this.size;
        }

        private void checkForComodification() {
            if (ArrayList.this.modCount != this.modCount)
                throw new ConcurrentModificationException();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值