ArrayList类注释翻译、源码分析

来源:互联网 发布:制作视频的软件 编辑:程序博客网 时间:2024/06/05 13:19

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();        }    }}
原创粉丝点击