ArrayList

  1. /* 
  2.  * @(#)ArrayList.java   1.56 06/04/21 
  3.  * 
  4.  * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 
  5.  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 
  6.  */  
  7. package java.util;  
  8. /** 
  9.  * Resizable-array implementation of the <tt>List</tt> interface.  Implements 
  10.  * all optional list operations, and permits all elements, including 
  11.  * <tt>null</tt>.  In addition to implementing the <tt>List</tt> interface, 
  12.  * this class provides methods to manipulate the size of the array that is 
  13.  * used internally to store the list.  (This class is roughly equivalent to 
  14.  * <tt>Vector</tt>, except that it is unsynchronized.)<p> 
  15.  * 
  16.  * The <tt>size</tt>, <tt>isEmpty</tt>, <tt>get</tt>, <tt>set</tt>, 
  17.  * <tt>iterator</tt>, and <tt>listIterator</tt> operations run in constant 
  18.  * time.  The <tt>add</tt> operation runs in <i>amortized constant time</i>, 
  19.  * that is, adding n elements requires O(n) time.  All of the other operations 
  20.  * run in linear time (roughly speaking).  The constant factor is low compared 
  21.  * to that for the <tt>LinkedList</tt> implementation.<p> 
  22.  * 
  23.  * Each <tt>ArrayList</tt> instance has a <i>capacity</i>.  The capacity is 
  24.  * the size of the array used to store the elements in the list.  It is always 
  25.  * at least as large as the list size.  As elements are added to an ArrayList, 
  26.  * its capacity grows automatically.  The details of the growth policy are not 
  27.  * specified beyond the fact that adding an element has constant amortized 
  28.  * time cost.<p> 
  29.  * 
  30.  * An application can increase the capacity of an <tt>ArrayList</tt> instance 
  31.  * before adding a large number of elements using the <tt>ensureCapacity</tt> 
  32.  * operation.  This may reduce the amount of incremental reallocation. 
  33.  * 
  34.  * <p><strong>Note that this implementation is not synchronized.</strong> 
  35.  * If multiple threads access an <tt>ArrayList</tt> instance concurrently, 
  36.  * and at least one of the threads modifies the list structurally, it 
  37.  * <i>must</i> be synchronized externally.  (A structural modification is 
  38.  * any operation that adds or deletes one or more elements, or explicitly 
  39.  * resizes the backing array; merely setting the value of an element is not 
  40.  * a structural modification.)  This is typically accomplished by 
  41.  * synchronizing on some object that naturally encapsulates the list. 
  42.  * 
  43.  * If no such object exists, the list should be "wrapped" using the 
  44.  * {@link Collections#synchronizedList Collections.synchronizedList} 
  45.  * method.  This is best done at creation time, to prevent accidental 
  46.  * unsynchronized access to the list:<pre> 
  47.  *   List list = Collections.synchronizedList(new ArrayList(...));</pre> 
  48.  * 
  49.  * <p>The iterators returned by this class's <tt>iterator</tt> and 
  50.  * <tt>listIterator</tt> methods are <i>fail-fast</i>: if the list is 
  51.  * structurally modified at any time after the iterator is created, in any way 
  52.  * except through the iterator's own <tt>remove</tt> or <tt>add</tt> methods, 
  53.  * the iterator will throw a {@link ConcurrentModificationException}.  Thus, in 
  54.  * the face of concurrent modification, the iterator fails quickly and cleanly, 
  55.  * rather than risking arbitrary, non-deterministic behavior at an undetermined 
  56.  * time in the future.<p> 
  57.  * 
  58.  * Note that the fail-fast behavior of an iterator cannot be guaranteed 
  59.  * as it is, generally speaking, impossible to make any hard guarantees in the 
  60.  * presence of unsynchronized concurrent modification.  Fail-fast iterators 
  61.  * throw <tt>ConcurrentModificationException</tt> on a best-effort basis. 
  62.  * Therefore, it would be wrong to write a program that depended on this 
  63.  * exception for its correctness: <i>the fail-fast behavior of iterators 
  64.  * should be used only to detect bugs.</i><p> 
  65.  * 
  66.  * This class is a member of the 
  67.  * <a href="{@docRoot}/../technotes/guides/collections/index.html" mce_href="technotes/guides/collections/index.html"> 
  68.  * Java Collections Framework</a>. 
  69.  * 
  70.  * @author  Josh Bloch 
  71.  * @author  Neal Gafter 
  72.  * @version 1.56, 04/21/06 
  73.  * @see     Collection 
  74.  * @see     List 
  75.  * @see     LinkedList 
  76.  * @see     Vector 
  77.  * @since   1.2 
  78.  */  
  79. public class ArrayList<E> extends AbstractList<E>  
  80.         implements List<E>, RandomAccess, Cloneable, java.io.Serializable  
  81. {  
  82.     private static final long serialVersionUID = 8683452581122892189L;  
  83.     /** 
  84.      * The array buffer into which the elements of the ArrayList are stored. 
  85.      * The capacity of the ArrayList is the length of this array buffer. 
  86.      */  
  87.     private transient Object[] elementData;  
  88.     /** 
  89.      * The size of the ArrayList (the number of elements it contains). 
  90.      * 
  91.      * @serial 
  92.      */  
  93.     private int size;  
  94.     /** 
  95.      * Constructs an empty list with the specified initial capacity. 
  96.      * 
  97.      * @param   initialCapacity   the initial capacity of the list 
  98.      * @exception IllegalArgumentException if the specified initial capacity 
  99.      *            is negative 
  100.      */  
  101.     public ArrayList(int initialCapacity) {  
  102.     super();  
  103.         if (initialCapacity < 0)  
  104.             throw new IllegalArgumentException("Illegal Capacity: "+  
  105.                                                initialCapacity);  
  106.     this.elementData = new Object[initialCapacity];  
  107.     }  
  108.     /** 
  109.      * Constructs an empty list with an initial capacity of ten. 
  110.      */  
  111.     public ArrayList() {  
  112.     this(10);  
  113.     }  
  114.     /** 
  115.      * Constructs a list containing the elements of the specified 
  116.      * collection, in the order they are returned by the collection's 
  117.      * iterator. 
  118.      * 
  119.      * @param c the collection whose elements are to be placed into this list 
  120.      * @throws NullPointerException if the specified collection is null 
  121.      */  
  122.     public ArrayList(Collection<? extends E> c) {  
  123.     elementData = c.toArray();  
  124.     size = elementData.length;  
  125.     // c.toArray might (incorrectly) not return Object[] (see 6260652)  
  126.     if (elementData.getClass() != Object[].class)  
  127.         elementData = Arrays.copyOf(elementData, size, Object[].class);  
  128.     }  
  129.     /** 
  130.      * Trims the capacity of this <tt>ArrayList</tt> instance to be the 
  131.      * list's current size.  An application can use this operation to minimize 
  132.      * the storage of an <tt>ArrayList</tt> instance. 
  133.      */  
  134.     public void trimToSize() {  
  135.     modCount++;  
  136.     int oldCapacity = elementData.length;  
  137.     if (size < oldCapacity) {  
  138.             elementData = Arrays.copyOf(elementData, size);  
  139.     }  
  140.     }  
  141.     /** 
  142.      * Increases the capacity of this <tt>ArrayList</tt> instance, if 
  143.      * necessary, to ensure that it can hold at least the number of elements 
  144.      * specified by the minimum capacity argument. 
  145.      * 
  146.      * @param   minCapacity   the desired minimum capacity 
  147.      */  
  148.     public void ensureCapacity(int minCapacity) {  
  149.     modCount++;  
  150.     int oldCapacity = elementData.length;  
  151.     if (minCapacity > oldCapacity) {  
  152.         Object oldData[] = elementData;  
  153.         int newCapacity = (oldCapacity * 3)/2 + 1;  
  154.             if (newCapacity < minCapacity)  
  155.         newCapacity = minCapacity;  
  156.             // minCapacity is usually close to size, so this is a win:  
  157.             elementData = Arrays.copyOf(elementData, newCapacity);  
  158.     }  
  159.     }  
  160.     /** 
  161.      * Returns the number of elements in this list. 
  162.      * 
  163.      * @return the number of elements in this list 
  164.      */  
  165.     public int size() {  
  166.     return size;  
  167.     }  
  168.     /** 
  169.      * Returns <tt>true</tt> if this list contains no elements. 
  170.      * 
  171.      * @return <tt>true</tt> if this list contains no elements 
  172.      */  
  173.     public boolean isEmpty() {  
  174.     return size == 0;  
  175.     }  
  176.     /** 
  177.      * Returns <tt>true</tt> if this list contains the specified element. 
  178.      * More formally, returns <tt>true</tt> if and only if this list contains 
  179.      * at least one element <tt>e</tt> such that 
  180.      * <tt>(o==null ? e==null : o.equals(e))</tt>. 
  181.      * 
  182.      * @param o element whose presence in this list is to be tested 
  183.      * @return <tt>true</tt> if this list contains the specified element 
  184.      */  
  185.     public boolean contains(Object o) {  
  186.     return indexOf(o) >= 0;  
  187.     }  
  188.     /** 
  189.      * Returns the index of the first occurrence of the specified element 
  190.      * in this list, or -1 if this list does not contain the element. 
  191.      * More formally, returns the lowest index <tt>i</tt> such that 
  192.      * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, 
  193.      * or -1 if there is no such index. 
  194.      */  
  195.     public int indexOf(Object o) {  
  196.     if (o == null) {  
  197.         for (int i = 0; i < size; i++)  
  198.         if (elementData[i]==null)  
  199.             return i;  
  200.     } else {  
  201.         for (int i = 0; i < size; i++)  
  202.         if (o.equals(elementData[i]))  
  203.             return i;  
  204.     }  
  205.     return -1;  
  206.     }  
  207.     /** 
  208.      * Returns the index of the last occurrence of the specified element 
  209.      * in this list, or -1 if this list does not contain the element. 
  210.      * More formally, returns the highest index <tt>i</tt> such that 
  211.      * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, 
  212.      * or -1 if there is no such index. 
  213.      */  
  214.     public int lastIndexOf(Object o) {  
  215.     if (o == null) {  
  216.         for (int i = size-1; i >= 0; i--)  
  217.         if (elementData[i]==null)  
  218.             return i;  
  219.     } else {  
  220.         for (int i = size-1; i >= 0; i--)  
  221.         if (o.equals(elementData[i]))  
  222.             return i;  
  223.     }  
  224.     return -1;  
  225.     }  
  226.     /** 
  227.      * Returns a shallow copy of this <tt>ArrayList</tt> instance.  (The 
  228.      * elements themselves are not copied.) 
  229.      * 
  230.      * @return a clone of this <tt>ArrayList</tt> instance 
  231.      */  
  232.     public Object clone() {  
  233.     try {  
  234.         ArrayList<E> v = (ArrayList<E>) super.clone();  
  235.         v.elementData = Arrays.copyOf(elementData, size);  
  236.         v.modCount = 0;  
  237.         return v;  
  238.     } catch (CloneNotSupportedException e) {  
  239.         // this shouldn't happen, since we are Cloneable  
  240.         throw new InternalError();  
  241.     }  
  242.     }  
  243.     /** 
  244.      * Returns an array containing all of the elements in this list 
  245.      * in proper sequence (from first to last element). 
  246.      * 
  247.      * <p>The returned array will be "safe" in that no references to it are 
  248.      * maintained by this list.  (In other words, this method must allocate 
  249.      * a new array).  The caller is thus free to modify the returned array. 
  250.      * 
  251.      * <p>This method acts as bridge between array-based and collection-based 
  252.      * APIs. 
  253.      * 
  254.      * @return an array containing all of the elements in this list in 
  255.      *         proper sequence 
  256.      */  
  257.     public Object[] toArray() {  
  258.         return Arrays.copyOf(elementData, size);  
  259.     }  
  260.     /** 
  261.      * Returns an array containing all of the elements in this list in proper 
  262.      * sequence (from first to last element); the runtime type of the returned 
  263.      * array is that of the specified array.  If the list fits in the 
  264.      * specified array, it is returned therein.  Otherwise, a new array is 
  265.      * allocated with the runtime type of the specified array and the size of 
  266.      * this list. 
  267.      * 
  268.      * <p>If the list fits in the specified array with room to spare 
  269.      * (i.e., the array has more elements than the list), the element in 
  270.      * the array immediately following the end of the collection is set to 
  271.      * <tt>null</tt>.  (This is useful in determining the length of the 
  272.      * list <i>only</i> if the caller knows that the list does not contain 
  273.      * any null elements.) 
  274.      * 
  275.      * @param a the array into which the elements of the list are to 
  276.      *          be stored, if it is big enough; otherwise, a new array of the 
  277.      *          same runtime type is allocated for this purpose. 
  278.      * @return an array containing the elements of the list 
  279.      * @throws ArrayStoreException if the runtime type of the specified array 
  280.      *         is not a supertype of the runtime type of every element in 
  281.      *         this list 
  282.      * @throws NullPointerException if the specified array is null 
  283.      */  
  284.     public <T> T[] toArray(T[] a) {  
  285.         if (a.length < size)  
  286.             // Make a new array of a's runtime type, but my contents:  
  287.             return (T[]) Arrays.copyOf(elementData, size, a.getClass());  
  288.     System.arraycopy(elementData, 0, a, 0, size);  
  289.         if (a.length > size)  
  290.             a[size] = null;  
  291.         return a;  
  292.     }  
  293.     // Positional Access Operations  
  294.     /** 
  295.      * Returns the element at the specified position in this list. 
  296.      * 
  297.      * @param  index index of the element to return 
  298.      * @return the element at the specified position in this list 
  299.      * @throws IndexOutOfBoundsException {@inheritDoc} 
  300.      */  
  301.     public E get(int index) {  
  302.     RangeCheck(index);  
  303.     return (E) elementData[index];  
  304.     }  
  305.     /** 
  306.      * Replaces the element at the specified position in this list with 
  307.      * the specified element. 
  308.      * 
  309.      * @param index index of the element to replace 
  310.      * @param element element to be stored at the specified position 
  311.      * @return the element previously at the specified position 
  312.      * @throws IndexOutOfBoundsException {@inheritDoc} 
  313.      */  
  314.     public E set(int index, E element) {  
  315.     RangeCheck(index);  
  316.     E oldValue = (E) elementData[index];  
  317.     elementData[index] = element;  
  318.     return oldValue;  
  319.     }  
  320.     /** 
  321.      * Appends the specified element to the end of this list. 
  322.      * 
  323.      * @param e element to be appended to this list 
  324.      * @return <tt>true</tt> (as specified by {@link Collection#add}) 
  325.      */  
  326.     public boolean add(E e) {  
  327.     ensureCapacity(size + 1);  // Increments modCount!!  
  328.     elementData[size++] = e;  
  329.     return true;  
  330.     }  
  331.     /** 
  332.      * Inserts the specified element at the specified position in this 
  333.      * list. Shifts the element currently at that position (if any) and 
  334.      * any subsequent elements to the right (adds one to their indices). 
  335.      * 
  336.      * @param index index at which the specified element is to be inserted 
  337.      * @param element element to be inserted 
  338.      * @throws IndexOutOfBoundsException {@inheritDoc} 
  339.      */  
  340.     public void add(int index, E element) {  
  341.     if (index > size || index < 0)  
  342.         throw new IndexOutOfBoundsException(  
  343.         "Index: "+index+", Size: "+size);  
  344.     ensureCapacity(size+1);  // Increments modCount!!  
  345.     System.arraycopy(elementData, index, elementData, index + 1,  
  346.              size - index);  
  347.     elementData[index] = element;  
  348.     size++;  
  349.     }  
  350.     /** 
  351.      * Removes the element at the specified position in this list. 
  352.      * Shifts any subsequent elements to the left (subtracts one from their 
  353.      * indices). 
  354.      * 
  355.      * @param index the index of the element to be removed 
  356.      * @return the element that was removed from the list 
  357.      * @throws IndexOutOfBoundsException {@inheritDoc} 
  358.      */  
  359.     public E remove(int index) {  
  360.     RangeCheck(index);  
  361.     modCount++;  
  362.     E oldValue = (E) elementData[index];  
  363.     int numMoved = size - index - 1;  
  364.     if (numMoved > 0)  
  365.         System.arraycopy(elementData, index+1, elementData, index,  
  366.                  numMoved);  
  367.     elementData[--size] = null// Let gc do its work  
  368.     return oldValue;  
  369.     }  
  370.     /** 
  371.      * Removes the first occurrence of the specified element from this list, 
  372.      * if it is present.  If the list does not contain the element, it is 
  373.      * unchanged.  More formally, removes the element with the lowest index 
  374.      * <tt>i</tt> such that 
  375.      * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt> 
  376.      * (if such an element exists).  Returns <tt>true</tt> if this list 
  377.      * contained the specified element (or equivalently, if this list 
  378.      * changed as a result of the call). 
  379.      * 
  380.      * @param o element to be removed from this list, if present 
  381.      * @return <tt>true</tt> if this list contained the specified element 
  382.      */  
  383.     public boolean remove(Object o) {  
  384.     if (o == null) {  
  385.             for (int index = 0; index < size; index++)  
  386.         if (elementData[index] == null) {  
  387.             fastRemove(index);  
  388.             return true;  
  389.         }  
  390.     } else {  
  391.         for (int index = 0; index < size; index++)  
  392.         if (o.equals(elementData[index])) {  
  393.             fastRemove(index);  
  394.             return true;  
  395.         }  
  396.         }  
  397.     return false;  
  398.     }  
  399.     /* 
  400.      * Private remove method that skips bounds checking and does not 
  401.      * return the value removed. 
  402.      */  
  403.     private void fastRemove(int index) {  
  404.         modCount++;  
  405.         int numMoved = size - index - 1;  
  406.         if (numMoved > 0)  
  407.             System.arraycopy(elementData, index+1, elementData, index,  
  408.                              numMoved);  
  409.         elementData[--size] = null// Let gc do its work  
  410.     }  
  411.     /** 
  412.      * Removes all of the elements from this list.  The list will 
  413.      * be empty after this call returns. 
  414.      */  
  415.     public void clear() {  
  416.     modCount++;  
  417.     // Let gc do its work  
  418.     for (int i = 0; i < size; i++)  
  419.         elementData[i] = null;  
  420.     size = 0;  
  421.     }  
  422.     /** 
  423.      * Appends all of the elements in the specified collection to the end of 
  424.      * this list, in the order that they are returned by the 
  425.      * specified collection's Iterator.  The behavior of this operation is 
  426.      * undefined if the specified collection is modified while the operation 
  427.      * is in progress.  (This implies that the behavior of this call is 
  428.      * undefined if the specified collection is this list, and this 
  429.      * list is nonempty.) 
  430.      * 
  431.      * @param c collection containing elements to be added to this list 
  432.      * @return <tt>true</tt> if this list changed as a result of the call 
  433.      * @throws NullPointerException if the specified collection is null 
  434.      */  
  435.     public boolean addAll(Collection<? extends E> c) {  
  436.     Object[] a = c.toArray();  
  437.         int numNew = a.length;  
  438.     ensureCapacity(size + numNew);  // Increments modCount  
  439.         System.arraycopy(a, 0, elementData, size, numNew);  
  440.         size += numNew;  
  441.     return numNew != 0;  
  442.     }  
  443.     /** 
  444.      * Inserts all of the elements in the specified collection into this 
  445.      * list, starting at the specified position.  Shifts the element 
  446.      * currently at that position (if any) and any subsequent elements to 
  447.      * the right (increases their indices).  The new elements will appear 
  448.      * in the list in the order that they are returned by the 
  449.      * specified collection's iterator. 
  450.      * 
  451.      * @param index index at which to insert the first element from the 
  452.      *              specified collection 
  453.      * @param c collection containing elements to be added to this list 
  454.      * @return <tt>true</tt> if this list changed as a result of the call 
  455.      * @throws IndexOutOfBoundsException {@inheritDoc} 
  456.      * @throws NullPointerException if the specified collection is null 
  457.      */  
  458.     public boolean addAll(int index, Collection<? extends E> c) {  
  459.     if (index > size || index < 0)  
  460.         throw new IndexOutOfBoundsException(  
  461.         "Index: " + index + ", Size: " + size);  
  462.     Object[] a = c.toArray();  
  463.     int numNew = a.length;  
  464.     ensureCapacity(size + numNew);  // Increments modCount  
  465.     int numMoved = size - index;  
  466.     if (numMoved > 0)  
  467.         System.arraycopy(elementData, index, elementData, index + numNew,  
  468.                  numMoved);  
  469.         System.arraycopy(a, 0, elementData, index, numNew);  
  470.     size += numNew;  
  471.     return numNew != 0;  
  472.     }  
  473.     /** 
  474.      * Removes from this list all of the elements whose index is between 
  475.      * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive. 
  476.      * Shifts any succeeding elements to the left (reduces their index). 
  477.      * This call shortens the list by <tt>(toIndex - fromIndex)</tt> elements. 
  478.      * (If <tt>toIndex==fromIndex</tt>, this operation has no effect.) 
  479.      * 
  480.      * @param fromIndex index of first element to be removed 
  481.      * @param toIndex index after last element to be removed 
  482.      * @throws IndexOutOfBoundsException if fromIndex or toIndex out of 
  483.      *              range (fromIndex < 0 || fromIndex >= size() || toIndex 
  484.      *              > size() || toIndex < fromIndex) 
  485.      */  
  486.     protected void removeRange(int fromIndex, int toIndex) {  
  487.     modCount++;  
  488.     int numMoved = size - toIndex;  
  489.         System.arraycopy(elementData, toIndex, elementData, fromIndex,  
  490.                          numMoved);  
  491.     // Let gc do its work  
  492.     int newSize = size - (toIndex-fromIndex);  
  493.     while (size != newSize)  
  494.         elementData[--size] = null;  
  495.     }  
  496.     /** 
  497.      * Checks if the given index is in range.  If not, throws an appropriate 
  498.      * runtime exception.  This method does *not* check if the index is 
  499.      * negative: It is always used immediately prior to an array access, 
  500.      * which throws an ArrayIndexOutOfBoundsException if index is negative. 
  501.      */  
  502.     private void RangeCheck(int index) {  
  503.     if (index >= size)  
  504.         throw new IndexOutOfBoundsException(  
  505.         "Index: "+index+", Size: "+size);  
  506.     }  
  507.     /** 
  508.      * Save the state of the <tt>ArrayList</tt> instance to a stream (that 
  509.      * is, serialize it). 
  510.      * 
  511.      * @serialData The length of the array backing the <tt>ArrayList</tt> 
  512.      *             instance is emitted (int), followed by all of its elements 
  513.      *             (each an <tt>Object</tt>) in the proper order. 
  514.      */  
  515.     private void writeObject(java.io.ObjectOutputStream s)  
  516.         throws java.io.IOException{  
  517.     // Write out element count, and any hidden stuff  
  518.     int expectedModCount = modCount;  
  519.     s.defaultWriteObject();  
  520.         // Write out array length  
  521.         s.writeInt(elementData.length);  
  522.     // Write out all elements in the proper order.  
  523.     for (int i=0; i<size; i++)  
  524.             s.writeObject(elementData[i]);  
  525.     if (modCount != expectedModCount) {  
  526.             throw new ConcurrentModificationException();  
  527.         }  
  528.     }  
  529.     /** 
  530.      * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is, 
  531.      * deserialize it). 
  532.      */  
  533.     private void readObject(java.io.ObjectInputStream s)  
  534.         throws java.io.IOException, ClassNotFoundException {  
  535.     // Read in size, and any hidden stuff  
  536.     s.defaultReadObject();  
  537.         // Read in array length and allocate array  
  538.         int arrayLength = s.readInt();  
  539.         Object[] a = elementData = new Object[arrayLength];  
  540.     // Read in all elements in the proper order.  
  541.     for (int i=0; i<size; i++)  
  542.             a[i] = s.readObject();  
  543.     }  
  544. }  
原文地址:https://www.cnblogs.com/Free-Thinker/p/3581494.html