rt/emul/compact/src/main/java/java/util/ArrayList.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 17 Jan 2017 07:04:06 +0100
changeset 1985 cd1cc103a03c
parent 636 8d0be6a9a809
permissions -rw-r--r--
Implementation of ClassValue for bck2brwsr
     1 /*
     2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 package java.util;
    27 
    28 
    29 /**
    30  * Resizable-array implementation of the <tt>List</tt> interface.  Implements
    31  * all optional list operations, and permits all elements, including
    32  * <tt>null</tt>.  In addition to implementing the <tt>List</tt> interface,
    33  * this class provides methods to manipulate the size of the array that is
    34  * used internally to store the list.  (This class is roughly equivalent to
    35  * <tt>Vector</tt>, except that it is unsynchronized.)
    36  *
    37  * <p>The <tt>size</tt>, <tt>isEmpty</tt>, <tt>get</tt>, <tt>set</tt>,
    38  * <tt>iterator</tt>, and <tt>listIterator</tt> operations run in constant
    39  * time.  The <tt>add</tt> operation runs in <i>amortized constant time</i>,
    40  * that is, adding n elements requires O(n) time.  All of the other operations
    41  * run in linear time (roughly speaking).  The constant factor is low compared
    42  * to that for the <tt>LinkedList</tt> implementation.
    43  *
    44  * <p>Each <tt>ArrayList</tt> instance has a <i>capacity</i>.  The capacity is
    45  * the size of the array used to store the elements in the list.  It is always
    46  * at least as large as the list size.  As elements are added to an ArrayList,
    47  * its capacity grows automatically.  The details of the growth policy are not
    48  * specified beyond the fact that adding an element has constant amortized
    49  * time cost.
    50  *
    51  * <p>An application can increase the capacity of an <tt>ArrayList</tt> instance
    52  * before adding a large number of elements using the <tt>ensureCapacity</tt>
    53  * operation.  This may reduce the amount of incremental reallocation.
    54  *
    55  * <p><strong>Note that this implementation is not synchronized.</strong>
    56  * If multiple threads access an <tt>ArrayList</tt> instance concurrently,
    57  * and at least one of the threads modifies the list structurally, it
    58  * <i>must</i> be synchronized externally.  (A structural modification is
    59  * any operation that adds or deletes one or more elements, or explicitly
    60  * resizes the backing array; merely setting the value of an element is not
    61  * a structural modification.)  This is typically accomplished by
    62  * synchronizing on some object that naturally encapsulates the list.
    63  *
    64  * If no such object exists, the list should be "wrapped" using the
    65  * {@link Collections#synchronizedList Collections.synchronizedList}
    66  * method.  This is best done at creation time, to prevent accidental
    67  * unsynchronized access to the list:<pre>
    68  *   List list = Collections.synchronizedList(new ArrayList(...));</pre>
    69  *
    70  * <p><a name="fail-fast"/>
    71  * The iterators returned by this class's {@link #iterator() iterator} and
    72  * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
    73  * if the list is structurally modified at any time after the iterator is
    74  * created, in any way except through the iterator's own
    75  * {@link ListIterator#remove() remove} or
    76  * {@link ListIterator#add(Object) add} methods, the iterator will throw a
    77  * {@link ConcurrentModificationException}.  Thus, in the face of
    78  * concurrent modification, the iterator fails quickly and cleanly, rather
    79  * than risking arbitrary, non-deterministic behavior at an undetermined
    80  * time in the future.
    81  *
    82  * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
    83  * as it is, generally speaking, impossible to make any hard guarantees in the
    84  * presence of unsynchronized concurrent modification.  Fail-fast iterators
    85  * throw {@code ConcurrentModificationException} on a best-effort basis.
    86  * Therefore, it would be wrong to write a program that depended on this
    87  * exception for its correctness:  <i>the fail-fast behavior of iterators
    88  * should be used only to detect bugs.</i>
    89  *
    90  * <p>This class is a member of the
    91  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
    92  * Java Collections Framework</a>.
    93  *
    94  * @author  Josh Bloch
    95  * @author  Neal Gafter
    96  * @see     Collection
    97  * @see     List
    98  * @see     LinkedList
    99  * @see     Vector
   100  * @since   1.2
   101  */
   102 
   103 public class ArrayList<E> extends AbstractList<E>
   104         implements List<E>, RandomAccess, Cloneable, java.io.Serializable
   105 {
   106     private static final long serialVersionUID = 8683452581122892189L;
   107 
   108     /**
   109      * The array buffer into which the elements of the ArrayList are stored.
   110      * The capacity of the ArrayList is the length of this array buffer.
   111      */
   112     private transient Object[] elementData;
   113 
   114     /**
   115      * The size of the ArrayList (the number of elements it contains).
   116      *
   117      * @serial
   118      */
   119     private int size;
   120 
   121     /**
   122      * Constructs an empty list with the specified initial capacity.
   123      *
   124      * @param  initialCapacity  the initial capacity of the list
   125      * @throws IllegalArgumentException if the specified initial capacity
   126      *         is negative
   127      */
   128     public ArrayList(int initialCapacity) {
   129         super();
   130         if (initialCapacity < 0)
   131             throw new IllegalArgumentException("Illegal Capacity: "+
   132                                                initialCapacity);
   133         this.elementData = new Object[initialCapacity];
   134     }
   135 
   136     /**
   137      * Constructs an empty list with an initial capacity of ten.
   138      */
   139     public ArrayList() {
   140         this(10);
   141     }
   142 
   143     /**
   144      * Constructs a list containing the elements of the specified
   145      * collection, in the order they are returned by the collection's
   146      * iterator.
   147      *
   148      * @param c the collection whose elements are to be placed into this list
   149      * @throws NullPointerException if the specified collection is null
   150      */
   151     public ArrayList(Collection<? extends E> c) {
   152         elementData = c.toArray();
   153         size = elementData.length;
   154         // c.toArray might (incorrectly) not return Object[] (see 6260652)
   155         if (elementData.getClass() != Object[].class)
   156             elementData = Arrays.copyOf(elementData, size, Object[].class);
   157     }
   158 
   159     /**
   160      * Trims the capacity of this <tt>ArrayList</tt> instance to be the
   161      * list's current size.  An application can use this operation to minimize
   162      * the storage of an <tt>ArrayList</tt> instance.
   163      */
   164     public void trimToSize() {
   165         modCount++;
   166         int oldCapacity = elementData.length;
   167         if (size < oldCapacity) {
   168             elementData = Arrays.copyOf(elementData, size);
   169         }
   170     }
   171 
   172     /**
   173      * Increases the capacity of this <tt>ArrayList</tt> instance, if
   174      * necessary, to ensure that it can hold at least the number of elements
   175      * specified by the minimum capacity argument.
   176      *
   177      * @param   minCapacity   the desired minimum capacity
   178      */
   179     public void ensureCapacity(int minCapacity) {
   180         if (minCapacity > 0)
   181             ensureCapacityInternal(minCapacity);
   182     }
   183 
   184     private void ensureCapacityInternal(int minCapacity) {
   185         modCount++;
   186         // overflow-conscious code
   187         if (minCapacity - elementData.length > 0)
   188             grow(minCapacity);
   189     }
   190 
   191     /**
   192      * The maximum size of array to allocate.
   193      * Some VMs reserve some header words in an array.
   194      * Attempts to allocate larger arrays may result in
   195      * OutOfMemoryError: Requested array size exceeds VM limit
   196      */
   197     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
   198 
   199     /**
   200      * Increases the capacity to ensure that it can hold at least the
   201      * number of elements specified by the minimum capacity argument.
   202      *
   203      * @param minCapacity the desired minimum capacity
   204      */
   205     private void grow(int minCapacity) {
   206         // overflow-conscious code
   207         int oldCapacity = elementData.length;
   208         int newCapacity = oldCapacity + (oldCapacity >> 1);
   209         if (newCapacity - minCapacity < 0)
   210             newCapacity = minCapacity;
   211         if (newCapacity - MAX_ARRAY_SIZE > 0)
   212             newCapacity = hugeCapacity(minCapacity);
   213         // minCapacity is usually close to size, so this is a win:
   214         elementData = Arrays.copyOf(elementData, newCapacity);
   215     }
   216 
   217     private static int hugeCapacity(int minCapacity) {
   218         if (minCapacity < 0) // overflow
   219             throw new OutOfMemoryError();
   220         return (minCapacity > MAX_ARRAY_SIZE) ?
   221             Integer.MAX_VALUE :
   222             MAX_ARRAY_SIZE;
   223     }
   224 
   225     /**
   226      * Returns the number of elements in this list.
   227      *
   228      * @return the number of elements in this list
   229      */
   230     public int size() {
   231         return size;
   232     }
   233 
   234     /**
   235      * Returns <tt>true</tt> if this list contains no elements.
   236      *
   237      * @return <tt>true</tt> if this list contains no elements
   238      */
   239     public boolean isEmpty() {
   240         return size == 0;
   241     }
   242 
   243     /**
   244      * Returns <tt>true</tt> if this list contains the specified element.
   245      * More formally, returns <tt>true</tt> if and only if this list contains
   246      * at least one element <tt>e</tt> such that
   247      * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
   248      *
   249      * @param o element whose presence in this list is to be tested
   250      * @return <tt>true</tt> if this list contains the specified element
   251      */
   252     public boolean contains(Object o) {
   253         return indexOf(o) >= 0;
   254     }
   255 
   256     /**
   257      * Returns the index of the first occurrence of the specified element
   258      * in this list, or -1 if this list does not contain the element.
   259      * More formally, returns the lowest index <tt>i</tt> such that
   260      * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
   261      * or -1 if there is no such index.
   262      */
   263     public int indexOf(Object o) {
   264         if (o == null) {
   265             for (int i = 0; i < size; i++)
   266                 if (elementData[i]==null)
   267                     return i;
   268         } else {
   269             for (int i = 0; i < size; i++)
   270                 if (o.equals(elementData[i]))
   271                     return i;
   272         }
   273         return -1;
   274     }
   275 
   276     /**
   277      * Returns the index of the last occurrence of the specified element
   278      * in this list, or -1 if this list does not contain the element.
   279      * More formally, returns the highest index <tt>i</tt> such that
   280      * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
   281      * or -1 if there is no such index.
   282      */
   283     public int lastIndexOf(Object o) {
   284         if (o == null) {
   285             for (int i = size-1; i >= 0; i--)
   286                 if (elementData[i]==null)
   287                     return i;
   288         } else {
   289             for (int i = size-1; i >= 0; i--)
   290                 if (o.equals(elementData[i]))
   291                     return i;
   292         }
   293         return -1;
   294     }
   295 
   296     /**
   297      * Returns a shallow copy of this <tt>ArrayList</tt> instance.  (The
   298      * elements themselves are not copied.)
   299      *
   300      * @return a clone of this <tt>ArrayList</tt> instance
   301      */
   302     public Object clone() {
   303         try {
   304             @SuppressWarnings("unchecked")
   305                 ArrayList<E> v = (ArrayList<E>) super.clone();
   306             v.elementData = Arrays.copyOf(elementData, size);
   307             v.modCount = 0;
   308             return v;
   309         } catch (CloneNotSupportedException e) {
   310             // this shouldn't happen, since we are Cloneable
   311             throw new InternalError();
   312         }
   313     }
   314 
   315     /**
   316      * Returns an array containing all of the elements in this list
   317      * in proper sequence (from first to last element).
   318      *
   319      * <p>The returned array will be "safe" in that no references to it are
   320      * maintained by this list.  (In other words, this method must allocate
   321      * a new array).  The caller is thus free to modify the returned array.
   322      *
   323      * <p>This method acts as bridge between array-based and collection-based
   324      * APIs.
   325      *
   326      * @return an array containing all of the elements in this list in
   327      *         proper sequence
   328      */
   329     public Object[] toArray() {
   330         return Arrays.copyOf(elementData, size);
   331     }
   332 
   333     /**
   334      * Returns an array containing all of the elements in this list in proper
   335      * sequence (from first to last element); the runtime type of the returned
   336      * array is that of the specified array.  If the list fits in the
   337      * specified array, it is returned therein.  Otherwise, a new array is
   338      * allocated with the runtime type of the specified array and the size of
   339      * this list.
   340      *
   341      * <p>If the list fits in the specified array with room to spare
   342      * (i.e., the array has more elements than the list), the element in
   343      * the array immediately following the end of the collection is set to
   344      * <tt>null</tt>.  (This is useful in determining the length of the
   345      * list <i>only</i> if the caller knows that the list does not contain
   346      * any null elements.)
   347      *
   348      * @param a the array into which the elements of the list are to
   349      *          be stored, if it is big enough; otherwise, a new array of the
   350      *          same runtime type is allocated for this purpose.
   351      * @return an array containing the elements of the list
   352      * @throws ArrayStoreException if the runtime type of the specified array
   353      *         is not a supertype of the runtime type of every element in
   354      *         this list
   355      * @throws NullPointerException if the specified array is null
   356      */
   357     @SuppressWarnings("unchecked")
   358     public <T> T[] toArray(T[] a) {
   359         if (a.length < size)
   360             // Make a new array of a's runtime type, but my contents:
   361             return (T[]) Arrays.copyOf(elementData, size, a.getClass());
   362         System.arraycopy(elementData, 0, a, 0, size);
   363         if (a.length > size)
   364             a[size] = null;
   365         return a;
   366     }
   367 
   368     // Positional Access Operations
   369 
   370     @SuppressWarnings("unchecked")
   371     E elementData(int index) {
   372         return (E) elementData[index];
   373     }
   374 
   375     /**
   376      * Returns the element at the specified position in this list.
   377      *
   378      * @param  index index of the element to return
   379      * @return the element at the specified position in this list
   380      * @throws IndexOutOfBoundsException {@inheritDoc}
   381      */
   382     public E get(int index) {
   383         rangeCheck(index);
   384 
   385         return elementData(index);
   386     }
   387 
   388     /**
   389      * Replaces the element at the specified position in this list with
   390      * the specified element.
   391      *
   392      * @param index index of the element to replace
   393      * @param element element to be stored at the specified position
   394      * @return the element previously at the specified position
   395      * @throws IndexOutOfBoundsException {@inheritDoc}
   396      */
   397     public E set(int index, E element) {
   398         rangeCheck(index);
   399 
   400         E oldValue = elementData(index);
   401         elementData[index] = element;
   402         return oldValue;
   403     }
   404 
   405     /**
   406      * Appends the specified element to the end of this list.
   407      *
   408      * @param e element to be appended to this list
   409      * @return <tt>true</tt> (as specified by {@link Collection#add})
   410      */
   411     public boolean add(E e) {
   412         ensureCapacityInternal(size + 1);  // Increments modCount!!
   413         elementData[size++] = e;
   414         return true;
   415     }
   416 
   417     /**
   418      * Inserts the specified element at the specified position in this
   419      * list. Shifts the element currently at that position (if any) and
   420      * any subsequent elements to the right (adds one to their indices).
   421      *
   422      * @param index index at which the specified element is to be inserted
   423      * @param element element to be inserted
   424      * @throws IndexOutOfBoundsException {@inheritDoc}
   425      */
   426     public void add(int index, E element) {
   427         rangeCheckForAdd(index);
   428 
   429         ensureCapacityInternal(size + 1);  // Increments modCount!!
   430         System.arraycopy(elementData, index, elementData, index + 1,
   431                          size - index);
   432         elementData[index] = element;
   433         size++;
   434     }
   435 
   436     /**
   437      * Removes the element at the specified position in this list.
   438      * Shifts any subsequent elements to the left (subtracts one from their
   439      * indices).
   440      *
   441      * @param index the index of the element to be removed
   442      * @return the element that was removed from the list
   443      * @throws IndexOutOfBoundsException {@inheritDoc}
   444      */
   445     public E remove(int index) {
   446         rangeCheck(index);
   447 
   448         modCount++;
   449         E oldValue = elementData(index);
   450 
   451         int numMoved = size - index - 1;
   452         if (numMoved > 0)
   453             System.arraycopy(elementData, index+1, elementData, index,
   454                              numMoved);
   455         elementData[--size] = null; // Let gc do its work
   456 
   457         return oldValue;
   458     }
   459 
   460     /**
   461      * Removes the first occurrence of the specified element from this list,
   462      * if it is present.  If the list does not contain the element, it is
   463      * unchanged.  More formally, removes the element with the lowest index
   464      * <tt>i</tt> such that
   465      * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
   466      * (if such an element exists).  Returns <tt>true</tt> if this list
   467      * contained the specified element (or equivalently, if this list
   468      * changed as a result of the call).
   469      *
   470      * @param o element to be removed from this list, if present
   471      * @return <tt>true</tt> if this list contained the specified element
   472      */
   473     public boolean remove(Object o) {
   474         if (o == null) {
   475             for (int index = 0; index < size; index++)
   476                 if (elementData[index] == null) {
   477                     fastRemove(index);
   478                     return true;
   479                 }
   480         } else {
   481             for (int index = 0; index < size; index++)
   482                 if (o.equals(elementData[index])) {
   483                     fastRemove(index);
   484                     return true;
   485                 }
   486         }
   487         return false;
   488     }
   489 
   490     /*
   491      * Private remove method that skips bounds checking and does not
   492      * return the value removed.
   493      */
   494     private void fastRemove(int index) {
   495         modCount++;
   496         int numMoved = size - index - 1;
   497         if (numMoved > 0)
   498             System.arraycopy(elementData, index+1, elementData, index,
   499                              numMoved);
   500         elementData[--size] = null; // Let gc do its work
   501     }
   502 
   503     /**
   504      * Removes all of the elements from this list.  The list will
   505      * be empty after this call returns.
   506      */
   507     public void clear() {
   508         modCount++;
   509 
   510         // Let gc do its work
   511         for (int i = 0; i < size; i++)
   512             elementData[i] = null;
   513 
   514         size = 0;
   515     }
   516 
   517     /**
   518      * Appends all of the elements in the specified collection to the end of
   519      * this list, in the order that they are returned by the
   520      * specified collection's Iterator.  The behavior of this operation is
   521      * undefined if the specified collection is modified while the operation
   522      * is in progress.  (This implies that the behavior of this call is
   523      * undefined if the specified collection is this list, and this
   524      * list is nonempty.)
   525      *
   526      * @param c collection containing elements to be added to this list
   527      * @return <tt>true</tt> if this list changed as a result of the call
   528      * @throws NullPointerException if the specified collection is null
   529      */
   530     public boolean addAll(Collection<? extends E> c) {
   531         Object[] a = c.toArray();
   532         int numNew = a.length;
   533         ensureCapacityInternal(size + numNew);  // Increments modCount
   534         System.arraycopy(a, 0, elementData, size, numNew);
   535         size += numNew;
   536         return numNew != 0;
   537     }
   538 
   539     /**
   540      * Inserts all of the elements in the specified collection into this
   541      * list, starting at the specified position.  Shifts the element
   542      * currently at that position (if any) and any subsequent elements to
   543      * the right (increases their indices).  The new elements will appear
   544      * in the list in the order that they are returned by the
   545      * specified collection's iterator.
   546      *
   547      * @param index index at which to insert the first element from the
   548      *              specified collection
   549      * @param c collection containing elements to be added to this list
   550      * @return <tt>true</tt> if this list changed as a result of the call
   551      * @throws IndexOutOfBoundsException {@inheritDoc}
   552      * @throws NullPointerException if the specified collection is null
   553      */
   554     public boolean addAll(int index, Collection<? extends E> c) {
   555         rangeCheckForAdd(index);
   556 
   557         Object[] a = c.toArray();
   558         int numNew = a.length;
   559         ensureCapacityInternal(size + numNew);  // Increments modCount
   560 
   561         int numMoved = size - index;
   562         if (numMoved > 0)
   563             System.arraycopy(elementData, index, elementData, index + numNew,
   564                              numMoved);
   565 
   566         System.arraycopy(a, 0, elementData, index, numNew);
   567         size += numNew;
   568         return numNew != 0;
   569     }
   570 
   571     /**
   572      * Removes from this list all of the elements whose index is between
   573      * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
   574      * Shifts any succeeding elements to the left (reduces their index).
   575      * This call shortens the list by {@code (toIndex - fromIndex)} elements.
   576      * (If {@code toIndex==fromIndex}, this operation has no effect.)
   577      *
   578      * @throws IndexOutOfBoundsException if {@code fromIndex} or
   579      *         {@code toIndex} is out of range
   580      *         ({@code fromIndex < 0 ||
   581      *          fromIndex >= size() ||
   582      *          toIndex > size() ||
   583      *          toIndex < fromIndex})
   584      */
   585     protected void removeRange(int fromIndex, int toIndex) {
   586         modCount++;
   587         int numMoved = size - toIndex;
   588         System.arraycopy(elementData, toIndex, elementData, fromIndex,
   589                          numMoved);
   590 
   591         // Let gc do its work
   592         int newSize = size - (toIndex-fromIndex);
   593         while (size != newSize)
   594             elementData[--size] = null;
   595     }
   596 
   597     /**
   598      * Checks if the given index is in range.  If not, throws an appropriate
   599      * runtime exception.  This method does *not* check if the index is
   600      * negative: It is always used immediately prior to an array access,
   601      * which throws an ArrayIndexOutOfBoundsException if index is negative.
   602      */
   603     private void rangeCheck(int index) {
   604         if (index >= size)
   605             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
   606     }
   607 
   608     /**
   609      * A version of rangeCheck used by add and addAll.
   610      */
   611     private void rangeCheckForAdd(int index) {
   612         if (index > size || index < 0)
   613             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
   614     }
   615 
   616     /**
   617      * Constructs an IndexOutOfBoundsException detail message.
   618      * Of the many possible refactorings of the error handling code,
   619      * this "outlining" performs best with both server and client VMs.
   620      */
   621     private String outOfBoundsMsg(int index) {
   622         return "Index: "+index+", Size: "+size;
   623     }
   624 
   625     /**
   626      * Removes from this list all of its elements that are contained in the
   627      * specified collection.
   628      *
   629      * @param c collection containing elements to be removed from this list
   630      * @return {@code true} if this list changed as a result of the call
   631      * @throws ClassCastException if the class of an element of this list
   632      *         is incompatible with the specified collection
   633      * (<a href="Collection.html#optional-restrictions">optional</a>)
   634      * @throws NullPointerException if this list contains a null element and the
   635      *         specified collection does not permit null elements
   636      * (<a href="Collection.html#optional-restrictions">optional</a>),
   637      *         or if the specified collection is null
   638      * @see Collection#contains(Object)
   639      */
   640     public boolean removeAll(Collection<?> c) {
   641         return batchRemove(c, false);
   642     }
   643 
   644     /**
   645      * Retains only the elements in this list that are contained in the
   646      * specified collection.  In other words, removes from this list all
   647      * of its elements that are not contained in the specified collection.
   648      *
   649      * @param c collection containing elements to be retained in this list
   650      * @return {@code true} if this list changed as a result of the call
   651      * @throws ClassCastException if the class of an element of this list
   652      *         is incompatible with the specified collection
   653      * (<a href="Collection.html#optional-restrictions">optional</a>)
   654      * @throws NullPointerException if this list contains a null element and the
   655      *         specified collection does not permit null elements
   656      * (<a href="Collection.html#optional-restrictions">optional</a>),
   657      *         or if the specified collection is null
   658      * @see Collection#contains(Object)
   659      */
   660     public boolean retainAll(Collection<?> c) {
   661         return batchRemove(c, true);
   662     }
   663 
   664     private boolean batchRemove(Collection<?> c, boolean complement) {
   665         final Object[] elementData = this.elementData;
   666         int r = 0, w = 0;
   667         boolean modified = false;
   668         try {
   669             for (; r < size; r++)
   670                 if (c.contains(elementData[r]) == complement)
   671                     elementData[w++] = elementData[r];
   672         } finally {
   673             // Preserve behavioral compatibility with AbstractCollection,
   674             // even if c.contains() throws.
   675             if (r != size) {
   676                 System.arraycopy(elementData, r,
   677                                  elementData, w,
   678                                  size - r);
   679                 w += size - r;
   680             }
   681             if (w != size) {
   682                 for (int i = w; i < size; i++)
   683                     elementData[i] = null;
   684                 modCount += size - w;
   685                 size = w;
   686                 modified = true;
   687             }
   688         }
   689         return modified;
   690     }
   691 
   692     /**
   693      * Returns a list iterator over the elements in this list (in proper
   694      * sequence), starting at the specified position in the list.
   695      * The specified index indicates the first element that would be
   696      * returned by an initial call to {@link ListIterator#next next}.
   697      * An initial call to {@link ListIterator#previous previous} would
   698      * return the element with the specified index minus one.
   699      *
   700      * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
   701      *
   702      * @throws IndexOutOfBoundsException {@inheritDoc}
   703      */
   704     public ListIterator<E> listIterator(int index) {
   705         if (index < 0 || index > size)
   706             throw new IndexOutOfBoundsException("Index: "+index);
   707         return new ListItr(index);
   708     }
   709 
   710     /**
   711      * Returns a list iterator over the elements in this list (in proper
   712      * sequence).
   713      *
   714      * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
   715      *
   716      * @see #listIterator(int)
   717      */
   718     public ListIterator<E> listIterator() {
   719         return new ListItr(0);
   720     }
   721 
   722     /**
   723      * Returns an iterator over the elements in this list in proper sequence.
   724      *
   725      * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
   726      *
   727      * @return an iterator over the elements in this list in proper sequence
   728      */
   729     public Iterator<E> iterator() {
   730         return new Itr();
   731     }
   732 
   733     /**
   734      * An optimized version of AbstractList.Itr
   735      */
   736     private class Itr implements Iterator<E> {
   737         int cursor;       // index of next element to return
   738         int lastRet = -1; // index of last element returned; -1 if no such
   739         int expectedModCount = modCount;
   740 
   741         public boolean hasNext() {
   742             return cursor != size;
   743         }
   744 
   745         @SuppressWarnings("unchecked")
   746         public E next() {
   747             checkForComodification();
   748             int i = cursor;
   749             if (i >= size)
   750                 throw new NoSuchElementException();
   751             Object[] elementData = ArrayList.this.elementData;
   752             if (i >= elementData.length)
   753                 throw new ConcurrentModificationException();
   754             cursor = i + 1;
   755             return (E) elementData[lastRet = i];
   756         }
   757 
   758         public void remove() {
   759             if (lastRet < 0)
   760                 throw new IllegalStateException();
   761             checkForComodification();
   762 
   763             try {
   764                 ArrayList.this.remove(lastRet);
   765                 cursor = lastRet;
   766                 lastRet = -1;
   767                 expectedModCount = modCount;
   768             } catch (IndexOutOfBoundsException ex) {
   769                 throw new ConcurrentModificationException();
   770             }
   771         }
   772 
   773         final void checkForComodification() {
   774             if (modCount != expectedModCount)
   775                 throw new ConcurrentModificationException();
   776         }
   777     }
   778 
   779     /**
   780      * An optimized version of AbstractList.ListItr
   781      */
   782     private class ListItr extends Itr implements ListIterator<E> {
   783         ListItr(int index) {
   784             super();
   785             cursor = index;
   786         }
   787 
   788         public boolean hasPrevious() {
   789             return cursor != 0;
   790         }
   791 
   792         public int nextIndex() {
   793             return cursor;
   794         }
   795 
   796         public int previousIndex() {
   797             return cursor - 1;
   798         }
   799 
   800         @SuppressWarnings("unchecked")
   801         public E previous() {
   802             checkForComodification();
   803             int i = cursor - 1;
   804             if (i < 0)
   805                 throw new NoSuchElementException();
   806             Object[] elementData = ArrayList.this.elementData;
   807             if (i >= elementData.length)
   808                 throw new ConcurrentModificationException();
   809             cursor = i;
   810             return (E) elementData[lastRet = i];
   811         }
   812 
   813         public void set(E e) {
   814             if (lastRet < 0)
   815                 throw new IllegalStateException();
   816             checkForComodification();
   817 
   818             try {
   819                 ArrayList.this.set(lastRet, e);
   820             } catch (IndexOutOfBoundsException ex) {
   821                 throw new ConcurrentModificationException();
   822             }
   823         }
   824 
   825         public void add(E e) {
   826             checkForComodification();
   827 
   828             try {
   829                 int i = cursor;
   830                 ArrayList.this.add(i, e);
   831                 cursor = i + 1;
   832                 lastRet = -1;
   833                 expectedModCount = modCount;
   834             } catch (IndexOutOfBoundsException ex) {
   835                 throw new ConcurrentModificationException();
   836             }
   837         }
   838     }
   839 
   840     /**
   841      * Returns a view of the portion of this list between the specified
   842      * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.  (If
   843      * {@code fromIndex} and {@code toIndex} are equal, the returned list is
   844      * empty.)  The returned list is backed by this list, so non-structural
   845      * changes in the returned list are reflected in this list, and vice-versa.
   846      * The returned list supports all of the optional list operations.
   847      *
   848      * <p>This method eliminates the need for explicit range operations (of
   849      * the sort that commonly exist for arrays).  Any operation that expects
   850      * a list can be used as a range operation by passing a subList view
   851      * instead of a whole list.  For example, the following idiom
   852      * removes a range of elements from a list:
   853      * <pre>
   854      *      list.subList(from, to).clear();
   855      * </pre>
   856      * Similar idioms may be constructed for {@link #indexOf(Object)} and
   857      * {@link #lastIndexOf(Object)}, and all of the algorithms in the
   858      * {@link Collections} class can be applied to a subList.
   859      *
   860      * <p>The semantics of the list returned by this method become undefined if
   861      * the backing list (i.e., this list) is <i>structurally modified</i> in
   862      * any way other than via the returned list.  (Structural modifications are
   863      * those that change the size of this list, or otherwise perturb it in such
   864      * a fashion that iterations in progress may yield incorrect results.)
   865      *
   866      * @throws IndexOutOfBoundsException {@inheritDoc}
   867      * @throws IllegalArgumentException {@inheritDoc}
   868      */
   869     public List<E> subList(int fromIndex, int toIndex) {
   870         subListRangeCheck(fromIndex, toIndex, size);
   871         return new SubList(this, 0, fromIndex, toIndex);
   872     }
   873 
   874     static void subListRangeCheck(int fromIndex, int toIndex, int size) {
   875         if (fromIndex < 0)
   876             throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
   877         if (toIndex > size)
   878             throw new IndexOutOfBoundsException("toIndex = " + toIndex);
   879         if (fromIndex > toIndex)
   880             throw new IllegalArgumentException("fromIndex(" + fromIndex +
   881                                                ") > toIndex(" + toIndex + ")");
   882     }
   883 
   884     private class SubList extends AbstractList<E> implements RandomAccess {
   885         private final AbstractList<E> parent;
   886         private final int parentOffset;
   887         private final int offset;
   888         int size;
   889 
   890         SubList(AbstractList<E> parent,
   891                 int offset, int fromIndex, int toIndex) {
   892             this.parent = parent;
   893             this.parentOffset = fromIndex;
   894             this.offset = offset + fromIndex;
   895             this.size = toIndex - fromIndex;
   896             this.modCount = ArrayList.this.modCount;
   897         }
   898 
   899         public E set(int index, E e) {
   900             rangeCheck(index);
   901             checkForComodification();
   902             E oldValue = ArrayList.this.elementData(offset + index);
   903             ArrayList.this.elementData[offset + index] = e;
   904             return oldValue;
   905         }
   906 
   907         public E get(int index) {
   908             rangeCheck(index);
   909             checkForComodification();
   910             return ArrayList.this.elementData(offset + index);
   911         }
   912 
   913         public int size() {
   914             checkForComodification();
   915             return this.size;
   916         }
   917 
   918         public void add(int index, E e) {
   919             rangeCheckForAdd(index);
   920             checkForComodification();
   921             parent.add(parentOffset + index, e);
   922             this.modCount = parent.modCount;
   923             this.size++;
   924         }
   925 
   926         public E remove(int index) {
   927             rangeCheck(index);
   928             checkForComodification();
   929             E result = parent.remove(parentOffset + index);
   930             this.modCount = parent.modCount;
   931             this.size--;
   932             return result;
   933         }
   934 
   935         protected void removeRange(int fromIndex, int toIndex) {
   936             checkForComodification();
   937             parent.removeRange(parentOffset + fromIndex,
   938                                parentOffset + toIndex);
   939             this.modCount = parent.modCount;
   940             this.size -= toIndex - fromIndex;
   941         }
   942 
   943         public boolean addAll(Collection<? extends E> c) {
   944             return addAll(this.size, c);
   945         }
   946 
   947         public boolean addAll(int index, Collection<? extends E> c) {
   948             rangeCheckForAdd(index);
   949             int cSize = c.size();
   950             if (cSize==0)
   951                 return false;
   952 
   953             checkForComodification();
   954             parent.addAll(parentOffset + index, c);
   955             this.modCount = parent.modCount;
   956             this.size += cSize;
   957             return true;
   958         }
   959 
   960         public Iterator<E> iterator() {
   961             return listIterator();
   962         }
   963 
   964         public ListIterator<E> listIterator(final int index) {
   965             checkForComodification();
   966             rangeCheckForAdd(index);
   967             final int offset = this.offset;
   968 
   969             return new ListIterator<E>() {
   970                 int cursor = index;
   971                 int lastRet = -1;
   972                 int expectedModCount = ArrayList.this.modCount;
   973 
   974                 public boolean hasNext() {
   975                     return cursor != SubList.this.size;
   976                 }
   977 
   978                 @SuppressWarnings("unchecked")
   979                 public E next() {
   980                     checkForComodification();
   981                     int i = cursor;
   982                     if (i >= SubList.this.size)
   983                         throw new NoSuchElementException();
   984                     Object[] elementData = ArrayList.this.elementData;
   985                     if (offset + i >= elementData.length)
   986                         throw new ConcurrentModificationException();
   987                     cursor = i + 1;
   988                     return (E) elementData[offset + (lastRet = i)];
   989                 }
   990 
   991                 public boolean hasPrevious() {
   992                     return cursor != 0;
   993                 }
   994 
   995                 @SuppressWarnings("unchecked")
   996                 public E previous() {
   997                     checkForComodification();
   998                     int i = cursor - 1;
   999                     if (i < 0)
  1000                         throw new NoSuchElementException();
  1001                     Object[] elementData = ArrayList.this.elementData;
  1002                     if (offset + i >= elementData.length)
  1003                         throw new ConcurrentModificationException();
  1004                     cursor = i;
  1005                     return (E) elementData[offset + (lastRet = i)];
  1006                 }
  1007 
  1008                 public int nextIndex() {
  1009                     return cursor;
  1010                 }
  1011 
  1012                 public int previousIndex() {
  1013                     return cursor - 1;
  1014                 }
  1015 
  1016                 public void remove() {
  1017                     if (lastRet < 0)
  1018                         throw new IllegalStateException();
  1019                     checkForComodification();
  1020 
  1021                     try {
  1022                         SubList.this.remove(lastRet);
  1023                         cursor = lastRet;
  1024                         lastRet = -1;
  1025                         expectedModCount = ArrayList.this.modCount;
  1026                     } catch (IndexOutOfBoundsException ex) {
  1027                         throw new ConcurrentModificationException();
  1028                     }
  1029                 }
  1030 
  1031                 public void set(E e) {
  1032                     if (lastRet < 0)
  1033                         throw new IllegalStateException();
  1034                     checkForComodification();
  1035 
  1036                     try {
  1037                         ArrayList.this.set(offset + lastRet, e);
  1038                     } catch (IndexOutOfBoundsException ex) {
  1039                         throw new ConcurrentModificationException();
  1040                     }
  1041                 }
  1042 
  1043                 public void add(E e) {
  1044                     checkForComodification();
  1045 
  1046                     try {
  1047                         int i = cursor;
  1048                         SubList.this.add(i, e);
  1049                         cursor = i + 1;
  1050                         lastRet = -1;
  1051                         expectedModCount = ArrayList.this.modCount;
  1052                     } catch (IndexOutOfBoundsException ex) {
  1053                         throw new ConcurrentModificationException();
  1054                     }
  1055                 }
  1056 
  1057                 final void checkForComodification() {
  1058                     if (expectedModCount != ArrayList.this.modCount)
  1059                         throw new ConcurrentModificationException();
  1060                 }
  1061             };
  1062         }
  1063 
  1064         public List<E> subList(int fromIndex, int toIndex) {
  1065             subListRangeCheck(fromIndex, toIndex, size);
  1066             return new SubList(this, offset, fromIndex, toIndex);
  1067         }
  1068 
  1069         private void rangeCheck(int index) {
  1070             if (index < 0 || index >= this.size)
  1071                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  1072         }
  1073 
  1074         private void rangeCheckForAdd(int index) {
  1075             if (index < 0 || index > this.size)
  1076                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  1077         }
  1078 
  1079         private String outOfBoundsMsg(int index) {
  1080             return "Index: "+index+", Size: "+this.size;
  1081         }
  1082 
  1083         private void checkForComodification() {
  1084             if (ArrayList.this.modCount != this.modCount)
  1085                 throw new ConcurrentModificationException();
  1086         }
  1087     }
  1088 }