ArrayList類註釋翻譯、源碼分析

HashMap源碼分析 :http://blog.csdn.net/disiwei1012/article/details/73530598
HashSet類註釋翻譯、fast-fail、源碼分析 :http://blog.csdn.net/disiwei1012/article/details/73692452
Hashtable類註釋翻譯、源碼分析 :http://blog.csdn.net/disiwei1012/article/details/73744181

一、類註釋翻譯

/**
 * Resizable -array implementation of the <tt> List</tt> interface.  Implements
 * all optional list operations, and permits all elements, including
 * <tt>null </tt> .  In addition to implementing the <tt> List</tt> interface,
 * this class provides methods to manipulate the size of the array that is
 * used internally to store the list.  (This class is roughly equivalent to
 * <tt>Vector </tt> , except that it is unsynchronized.)

用“可伸縮數組”來實現List接口。實現了所有List接口中的方法,並且允許存放所有元素,包括Null。
除了實現了List接口,本類還是提供操作數組大小的方法。(本類和Vector類似,只是本類是非同步的)

 * <p>The <tt> size</tt> , <tt>isEmpty </tt> , <tt> get </tt>, <tt> set</tt> ,
 * <tt>iterator </tt> , and <tt> listIterator </tt> operations run in constant
 * time.  The <tt> add</tt> operation runs in <i>amortized constant time</i> ,
 * that is, adding n elements requires O(n) time.  All of the other operations
 * run in linear time (roughly speaking).  The constant factor is low compared
 * to that for the <tt> LinkedList</tt> implementation.

size、isEmpty、get、set、iterator、listIterator 這些操作用的時間是常量,(也就是說這些操作與元素的個數無關,操作的時間爲o(1))。
add操作花費恆定分攤時間,也就是說插入n的元素的時間爲o(n),其實分攤之後,也就相當於插入一個元素的時間爲o(1)。
粗略的來說本類的其他操作都能在線性的時間內完成。(也就是說這些操作與元素的個成線性關係,操作的時間複雜度o(n))

What is meant by “Constant Amortized Time” when talking about time complexity of an algorithm?
https://stackoverflow.com/questions/200384/constant-amortized-time

 * <p>Each <tt> ArrayList</tt> instance has a <i> capacity</i> .  The capacity is
 * the size of the array used to store the elements in the list.  It is always
 * at least as large as the list size.  As elements are added to an ArrayList,
 * its capacity grows automatically.  The details of the growth policy are not
 * specified beyond the fact that adding an element has constant amortized
 * time cost.

每個ArrayList實例都有一個容量。這個容量也就是用來存儲元素的數組的大小,它至少等於list大小(list大小就是數組實際存放元素的個數)。
當一個元素被添加到集合中,這個集合的容量會自動增長。除了要求添加一個元素的效率爲“恆定分攤時間”,對於具體實現的細節沒有特別的要求。

 * <p>An application can increase the capacity of an <tt> ArrayList</tt> instance
 * before adding a large number of elements using the <tt> ensureCapacity</tt>
 * operation.  This may reduce the amount of incremental reallocation.

在大批量插入元素前,使用ensureCapacity操作來增加集合的容量。這或許能夠減少擴容之後新數組的大小。
【This may reduce the amount of incremental reallocation. 】這句的翻譯感覺有點怪怪的。

 * <p><strong>Note that this implementation is not synchronized.</strong>
 * If multiple threads access an <tt> ArrayList</tt> instance concurrently,
 * and at least one of the threads modifies the list structurally, it
 * <i>must </i> be synchronized externally.  (A structural modification is
 * any operation that adds or deletes one or more elements, or explicitly
 * resizes the backing array; merely setting the value of an element is not
 * a structural modification.)  This is typically accomplished by
 * synchronizing on some object that naturally encapsulates the list.

此類是非同步的。如果多個線程同時操作ArrayList實例,至少一個線程結構性的修改,必須要保證線程的同步。
(結構性修改:增加或刪除元素,或者調整數組大小,僅僅修改屬性的值不屬於結構性修改)
典型的實現是同步操作數組。

 * If no such object exists, the list should be "wrapped" using the
 * {@link Collections#synchronizedList Collections.synchronizedList}
 * method.  This is best done at creation time, to prevent accidental
 * unsynchronized access to the list: <pre>
 *   List list = Collections.synchronizedList(new ArrayList(...));</pre>

如果這種對象不存在,又想同步集合,可以這樣寫:

Collections.synchronizedList(new ArrayList(...))
 * <p><a name="fail-fast"/>
 * The iterators returned by this class's {@link #iterator() iterator} and
 * {@link #listIterator(int) listIterator} methods are <em> fail- fast </em>:
 * if the list is structurally modified at any time after the iterator is
 * created, in any way except through the iterator's own
 * {@link ListIterator#remove() remove} or
 * {@link ListIterator#add(Object) add} methods, the iterator will throw a
 * {@link ConcurrentModificationException}.  Thus, in the face of
 * concurrent modification, the iterator fails quickly and cleanly, rather
 * than risking arbitrary, non - deterministic behavior at an undetermined
 * time in the future.

 * <p>Note that the fail - fast behavior of an iterator cannot be guaranteed
 * as it is, generally speaking, impossible to make any hard guarantees in the
 * presence of unsynchronized concurrent modification.  Fail- fast iterators
 * throw {@code ConcurrentModificationException} on a best- effort basis.
 * Therefore, it would be wrong to write a program that depended on this
 * exception for its correctness:  <i> the fail- fast behavior of iterators
 * should be used only to detect bugs. </i>

關於fail-fast特性的介紹,請參考:http://www.cnblogs.com/skywang12345/p/3308762.html

二、源碼分析

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    private static final long serialVersionUID = 8683452581122892189L;

    /**
     * 實際用來存儲元素的地方,ArrayList的底層數據結構
     * 該數組的大小即爲ArrayList的容量
     */
    private transient Object[] elementData ;

    /**
     * ArrayList存儲元素個數
     *
     */
    private int size ;

    /**
     * 帶初始容量initialCapacity的構造函數
     */
    public ArrayList( int initialCapacity ) {
        super ();
        if (initialCapacity < 0)//如果初始容量小於0,拋出異常
            throw new IllegalArgumentException( "Illegal Capacity: "+
                                               initialCapacity );
        創建底層數據,大小爲initialCapacity
        this.elementData = new Object[ initialCapacity];
    }

    /**
     * 無參構造器,默認容量爲10
     */
    public ArrayList() {
        this (10);
    }

    /**
     * 創建一個參數爲集合對象c的構造函數,將c中的元素添加到ArrayList中
     * 通過迭代器返回的順序和和c中的一樣
     * @throws 如果c爲null,則拋出空指針異常
     */
    public ArrayList(Collection<? extends E> c ) {
        elementData = c .toArray();
        size = elementData .length ;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        //toArray有可能不返回Object[],具體參考:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6260652
        //如果toArray方法返回的不是Object[],則將elementData轉化成Object[],
        //爲ArrayList要能存放任何元素
        if (elementData .getClass() != Object[]. class)
            elementData = Arrays.copyOf( elementData , size , Object[]. class);
    }

    /**
     * 縮短ArrayList容量大小和存儲元素的個數相等
     */
    public void trimToSize() {
              //修改次數+1
        modCount++;
        int oldCapacity = elementData .length ;
        if (size < oldCapacity ) {//如果當前數組大小>實際存儲的元素個數,則縮小數組的大小
            elementData = Arrays.copyOf( elementData , size );
        }
    }

    /**
     * 爲了確保數組大小大於minCapacity,也就是數組大小大於需要存儲的元素個數,增加數組的大小
     * @param    minCapacity   the desired minimum capacity
     */
    public void ensureCapacity( int minCapacity ) {
        if (minCapacity > 0)
            //對數組進行擴容
            ensureCapacityInternal( minCapacity );
    }

    //數組擴容函數
    private void ensureCapacityInternal( int minCapacity) {
        modCount++;
        // overflow-conscious code
        if (minCapacity - elementData .length > 0)
            grow( minCapacity );
    }

    /**
     * 數組最大容量限制
     */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
     * 增加數組容量函數
     * @param minCapacity 渴望數組大小
     */
    private void grow(int minCapacity ) {
        // overflow-conscious code
        int oldCapacity = elementData .length ;
        //新數組大小爲原數組的1.5倍
        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 );
    }

    //如果新數組大小大於數組最大容量限制
    private static int hugeCapacity( int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer. MAX_VALUE :
            MAX_ARRAY_SIZE ;
    }

    /**
     * 獲取存儲元素個數
     */
    public int size() {
        return size ;
    }

    /**
     * 判斷是否存儲元素
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 集合中是否包含元素o
     */
    public boolean contains(Object o ) {
        return indexOf(o ) >= 0;
    }

    /**
     * 返回元素在集合中的位置(初次出現的位置)
     * 如果集合中不存在該元素,則返回-1,null不能放在equals的左邊
     */
    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;
    }

    /**
     * 返回元素在集合中的位置(最後出現的位置)
     * 如果集合中不存在該元素,則返回-1,null不能放在equals的左邊
     */
    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;
    }

    /**
     * 淺拷貝一個此ArrayList,並返回
     * @return a clone of this <tt> ArrayList </tt> instance
     */
    public Object clone() {
        try {
            @SuppressWarnings ("unchecked" )
            ArrayList<E> v = (ArrayList<E>) 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();
        }
    }

    /**
     *  返回一個包含全部元素的數組
     */
    public Object[] toArray() {
        return Arrays.copyOf( elementData , size );
    }

    /**
      * 返回一個指定類型包含全部元素的數組
     */
    @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);
        if (a .length > size )
            a[ size] = null ;
        return a ;
    }

    //返回數組指定位置上的元素
    E elementData( int index) {
        return (E) elementData [index ];
    }

    /**
     * 返回數組指定位置上的元素
     */
    public E get( int index ) {
        rangeCheck( index);

        return elementData(index );
    }

    /**
     * 替換數組指定位置上的元素
     */
    public E set( int index , E element ) {
        rangeCheck( index);

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

    /**
          * 在數組的尾部追加一個元素
     */
    public boolean add(E e ) {
        //先判斷數組是否需要擴容
        ensureCapacityInternal( size + 1);  // Increments modCount!!
        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).
     * 在指定位置插入元素
     */
    public void add(int index , E element ) {
        rangeCheckForAdd( index);
        //判斷元素是否需要擴容
        ensureCapacityInternal( size + 1);  // Increments modCount!!
        //System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
        //src:源數組;srcPos:源數組要複製的起始位置;dest:目的數組;destPos:目的數組放置的起始位置;length:複製的長度。
        //將元素該位置的元素以及之後的數組全部往後移植一位
        System. arraycopy( elementData, index, elementData , index + 1,size - index);
        elementData [index ] = element ;
        size++;
    }

    /**
     * Removes the element at the specified position in this list.
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).
     * 移除指定位置元素
     */
    public E remove( int index ) {
        rangeCheck( index);
        //修改次數+1
        modCount++;
        E oldValue = elementData( index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System. arraycopy( elementData, index+1, elementData , index , numMoved);
        //刪除最後一個數組元素的指針,即釋放最後一個數組元素指向的對象,讓GC能夠回收該對象
        //關於GC root不熟悉的看下JVM
        elementData [--size ] = null; // Let gc do its work
        //返回被移除位置的元素
        return oldValue ;
    }

    /**
     * 移除集合中的某個元素,如果集合中不存在該元素,則什麼都不做
     * 返回是否移除成功
     */
    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(Object o )方法的內部使用方法,私有。
     * 此方法相比remove(int index)有何特點?
     * 沒有進行範圍判斷,即rangeCheck( index);也不返回被刪除元素
     */
    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; // Let gc do its work
    }

    /**
     * 移除所有元素
     */
    public void clear() {
        modCount++;

        // Let gc do its work
        for (int i = 0; i < size ; i ++)
            elementData [i ] = null;

        size = 0;
    }

    /**
     * 追加集合c中的所有元素到ArrayList集合中,存放的先後順序保持不變。
          /
    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;

    }

    /**
     * 在執行位置插入集合c中的全部元素
     */
    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;
    }

    /**
      * 移除指定範圍內的元素
     */
    protected void removeRange( int fromIndex, int toIndex ) {
        modCount++;
        int numMoved = size - toIndex ;
        System. arraycopy( elementData, toIndex, elementData , fromIndex ,
                         numMoved);

        // Let gc do its work
        int newSize = size - (toIndex -fromIndex );
        while (size != newSize )
            elementData [--size ] = null;
    }

    /**
     * 檢測指定位置與元素個數大小,如果指定位置大於存儲元素個數,則拋出IndexOutOfBoundsException
     */
    private void rangeCheck( int index) {
        if (index >= size )
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index ));
    }

    /**
     * add and addAll操作判斷範圍的特有方法
     */
    private void rangeCheckForAdd( int index) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index ));
    }

    /**
     * Constructs an IndexOutOfBoundsException detail message.
     * 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 ;
    }

    /**
          * 移除與集合c有交集的元素,使用批量移除方法
     */
    public boolean removeAll(Collection<?> c ) {

        return batchRemove(c , false);
    }

    /**
     * 保留與集合c有交集的元素,使用批量移除方法
     */
    public boolean retainAll(Collection<?> c ) {
        return batchRemove(c , true);
    }

**下面詳細看下批量移除方法:batchRemove。
首先需要明確一點:數組也屬於引用數據類型,final Object[] elementData。對於引用類型而言,我們不能改變final修飾的引用的指向,但是我們可以修改指向的具體內容裏面的值。就以數組爲例:**

public static void main(String[] args) {
           final String[] s = {"a" ,"b" ,"c" };
           //不能修改指向
          // s = new String[5]; The final local variable s cannot be assigned. It must be blank and not using a compound assignment

          System.out.println(Arrays.toString(s));

          //雖然不能修改指向,但是我們可以修改指向對象中的內容
          s[0] = "d";
          s[1] = "e";
          s[2] = "f";

          System.out.println(Arrays.toString(s));

     }

輸出結果:
[a, b, c]
[d, e, f]

batchRemove定義一個引用指向元素組,然後對原數組中的元素進行操作。

private boolean batchRemove(Collection<?> c , boolean complement ) {
        final Object[] elementData = this. elementData;
        int r = 0, w = 0;
        boolean modified = false;
        try {
            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.
            if (r != size ) {
                System. arraycopy( elementData, r,
                                 elementData , w ,
                                 size - r);
                w += size - r;
            }
            if (w != size ) {
                for (int i = w ; i < size ; i ++)
                    elementData [i ] = null;
                modCount += size - w;
                size = w;
                modified = true ;
            }
        }
        return modified ;
    }
public ListIterator<E> listIterator( int index ) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException( "Index: "+ index);
        return new ListItr( index);
    }

    public ListIterator<E> listIterator() {
        return new ListItr(0);
    }

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

    /**
     * 實現Iterator接口的迭代器(內部使用)
     */
    private class Itr implements Iterator<E> {
        int cursor ;       // 指向當前元素的下一個元素
        int lastRet = -1; // 最後一個返回的元素的位置
        int expectedModCount = modCount ; //用來判斷是否拋出ConcurrentModificationException

        //是否還有下一個元素,如果下一個元素的位置小於存儲元素數量,返回true,否則false
        public boolean hasNext() {
            return cursor != size ;
        }

        //返回下一個元素
        @SuppressWarnings ("unchecked" )
        public E next() {
            //判斷是否拋出ConcurrentModificationException(即fast-fail)
            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;
            return (E) elementData [lastRet = i ];
        }

        //移除一個元素
        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            //判斷是否拋出ConcurrentModificationException(即fast-fail)
            checkForComodification();

            try {
                //移除最後一個返回的元素
                ArrayList. this .remove(lastRet );
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount ;
            } catch (IndexOutOfBoundsException ex ) {
                throw new ConcurrentModificationException();
            }
        }

        //fast-fail具體實現
        final void checkForComodification() {
            if (modCount != expectedModCount )
                throw new ConcurrentModificationException();
        }
    }

     /**
     * 實現ListIterator接口的迭代器(內部使用)
     */
    private class ListItr extends Itr implements ListIterator<E> {
       //構造函數
        ListItr( int index ) {
            super ();
            cursor = index;
        }
        //前面是否還有元素
        public boolean hasPrevious() {
            return cursor != 0;
        }
        //返回下一個元素位置
        public int nextIndex() {
            return cursor ;
        }
        //返回前一個元素位置
        public int previousIndex() {
            return cursor - 1;
        }

        //返回前一個元素
        @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 = i;
            return (E) elementData [lastRet = i ];
        }
        //設置一個元素
        public void set(E e ) {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList. this .set(lastRet , e );
            } catch (IndexOutOfBoundsException ex ) {
                throw new ConcurrentModificationException();
            }
        }
        //增加一個元素
        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();
            }
        }
    }

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

    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 + ")");
    }

//方法返回的List是ArrayList中某段數據的一個視圖. 因此, 在操作此方法返回的List時, 同樣會改變ArrayList的數據.
    //對於結構性修改,通過該類修改,不會導致fast-false;但父ArrayList修改會導致該類的fast-false
    private class SubList extends AbstractList<E> implements RandomAccess {
        private final AbstractList<E> parent;
        private final int parentOffset;
        private final int offset;
        int size ;

        //parent 父類型
        //offset 父類型的偏移量
        //fromIndex 子列表的開始元素,位於父列表的位置
        //toIndex 子列表的結束元素,位於父列表的位置
        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();
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章