rt/emul/compact/src/main/java/java/util/Vector.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 26 Feb 2013 16:54:16 +0100
changeset 772 d382dacfd73f
parent 636 emul/compact/src/main/java/java/util/Vector.java@8d0be6a9a809
permissions -rw-r--r--
Moving modules around so the runtime is under one master pom and can be built without building other modules that are in the repository
     1 /*
     2  * Copyright (c) 1994, 2011, 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  * The {@code Vector} class implements a growable array of
    31  * objects. Like an array, it contains components that can be
    32  * accessed using an integer index. However, the size of a
    33  * {@code Vector} can grow or shrink as needed to accommodate
    34  * adding and removing items after the {@code Vector} has been created.
    35  *
    36  * <p>Each vector tries to optimize storage management by maintaining a
    37  * {@code capacity} and a {@code capacityIncrement}. The
    38  * {@code capacity} is always at least as large as the vector
    39  * size; it is usually larger because as components are added to the
    40  * vector, the vector's storage increases in chunks the size of
    41  * {@code capacityIncrement}. An application can increase the
    42  * capacity of a vector before inserting a large number of
    43  * components; this reduces the amount of incremental reallocation.
    44  *
    45  * <p><a name="fail-fast"/>
    46  * The iterators returned by this class's {@link #iterator() iterator} and
    47  * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
    48  * if the vector is structurally modified at any time after the iterator is
    49  * created, in any way except through the iterator's own
    50  * {@link ListIterator#remove() remove} or
    51  * {@link ListIterator#add(Object) add} methods, the iterator will throw a
    52  * {@link ConcurrentModificationException}.  Thus, in the face of
    53  * concurrent modification, the iterator fails quickly and cleanly, rather
    54  * than risking arbitrary, non-deterministic behavior at an undetermined
    55  * time in the future.  The {@link Enumeration Enumerations} returned by
    56  * the {@link #elements() elements} method are <em>not</em> fail-fast.
    57  *
    58  * <p>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 {@code ConcurrentModificationException} 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>
    65  *
    66  * <p>As of the Java 2 platform v1.2, this class was retrofitted to
    67  * implement the {@link List} interface, making it a member of the
    68  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
    69  * Java Collections Framework</a>.  Unlike the new collection
    70  * implementations, {@code Vector} is synchronized.  If a thread-safe
    71  * implementation is not needed, it is recommended to use {@link
    72  * ArrayList} in place of {@code Vector}.
    73  *
    74  * @author  Lee Boynton
    75  * @author  Jonathan Payne
    76  * @see Collection
    77  * @see LinkedList
    78  * @since   JDK1.0
    79  */
    80 public class Vector<E>
    81     extends AbstractList<E>
    82     implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    83 {
    84     /**
    85      * The array buffer into which the components of the vector are
    86      * stored. The capacity of the vector is the length of this array buffer,
    87      * and is at least large enough to contain all the vector's elements.
    88      *
    89      * <p>Any array elements following the last element in the Vector are null.
    90      *
    91      * @serial
    92      */
    93     protected Object[] elementData;
    94 
    95     /**
    96      * The number of valid components in this {@code Vector} object.
    97      * Components {@code elementData[0]} through
    98      * {@code elementData[elementCount-1]} are the actual items.
    99      *
   100      * @serial
   101      */
   102     protected int elementCount;
   103 
   104     /**
   105      * The amount by which the capacity of the vector is automatically
   106      * incremented when its size becomes greater than its capacity.  If
   107      * the capacity increment is less than or equal to zero, the capacity
   108      * of the vector is doubled each time it needs to grow.
   109      *
   110      * @serial
   111      */
   112     protected int capacityIncrement;
   113 
   114     /** use serialVersionUID from JDK 1.0.2 for interoperability */
   115     private static final long serialVersionUID = -2767605614048989439L;
   116 
   117     /**
   118      * Constructs an empty vector with the specified initial capacity and
   119      * capacity increment.
   120      *
   121      * @param   initialCapacity     the initial capacity of the vector
   122      * @param   capacityIncrement   the amount by which the capacity is
   123      *                              increased when the vector overflows
   124      * @throws IllegalArgumentException if the specified initial capacity
   125      *         is negative
   126      */
   127     public Vector(int initialCapacity, int capacityIncrement) {
   128         super();
   129         if (initialCapacity < 0)
   130             throw new IllegalArgumentException("Illegal Capacity: "+
   131                                                initialCapacity);
   132         this.elementData = new Object[initialCapacity];
   133         this.capacityIncrement = capacityIncrement;
   134     }
   135 
   136     /**
   137      * Constructs an empty vector with the specified initial capacity and
   138      * with its capacity increment equal to zero.
   139      *
   140      * @param   initialCapacity   the initial capacity of the vector
   141      * @throws IllegalArgumentException if the specified initial capacity
   142      *         is negative
   143      */
   144     public Vector(int initialCapacity) {
   145         this(initialCapacity, 0);
   146     }
   147 
   148     /**
   149      * Constructs an empty vector so that its internal data array
   150      * has size {@code 10} and its standard capacity increment is
   151      * zero.
   152      */
   153     public Vector() {
   154         this(10);
   155     }
   156 
   157     /**
   158      * Constructs a vector containing the elements of the specified
   159      * collection, in the order they are returned by the collection's
   160      * iterator.
   161      *
   162      * @param c the collection whose elements are to be placed into this
   163      *       vector
   164      * @throws NullPointerException if the specified collection is null
   165      * @since   1.2
   166      */
   167     public Vector(Collection<? extends E> c) {
   168         elementData = c.toArray();
   169         elementCount = elementData.length;
   170         // c.toArray might (incorrectly) not return Object[] (see 6260652)
   171         if (elementData.getClass() != Object[].class)
   172             elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
   173     }
   174 
   175     /**
   176      * Copies the components of this vector into the specified array.
   177      * The item at index {@code k} in this vector is copied into
   178      * component {@code k} of {@code anArray}.
   179      *
   180      * @param  anArray the array into which the components get copied
   181      * @throws NullPointerException if the given array is null
   182      * @throws IndexOutOfBoundsException if the specified array is not
   183      *         large enough to hold all the components of this vector
   184      * @throws ArrayStoreException if a component of this vector is not of
   185      *         a runtime type that can be stored in the specified array
   186      * @see #toArray(Object[])
   187      */
   188     public synchronized void copyInto(Object[] anArray) {
   189         System.arraycopy(elementData, 0, anArray, 0, elementCount);
   190     }
   191 
   192     /**
   193      * Trims the capacity of this vector to be the vector's current
   194      * size. If the capacity of this vector is larger than its current
   195      * size, then the capacity is changed to equal the size by replacing
   196      * its internal data array, kept in the field {@code elementData},
   197      * with a smaller one. An application can use this operation to
   198      * minimize the storage of a vector.
   199      */
   200     public synchronized void trimToSize() {
   201         modCount++;
   202         int oldCapacity = elementData.length;
   203         if (elementCount < oldCapacity) {
   204             elementData = Arrays.copyOf(elementData, elementCount);
   205         }
   206     }
   207 
   208     /**
   209      * Increases the capacity of this vector, if necessary, to ensure
   210      * that it can hold at least the number of components specified by
   211      * the minimum capacity argument.
   212      *
   213      * <p>If the current capacity of this vector is less than
   214      * {@code minCapacity}, then its capacity is increased by replacing its
   215      * internal data array, kept in the field {@code elementData}, with a
   216      * larger one.  The size of the new data array will be the old size plus
   217      * {@code capacityIncrement}, unless the value of
   218      * {@code capacityIncrement} is less than or equal to zero, in which case
   219      * the new capacity will be twice the old capacity; but if this new size
   220      * is still smaller than {@code minCapacity}, then the new capacity will
   221      * be {@code minCapacity}.
   222      *
   223      * @param minCapacity the desired minimum capacity
   224      */
   225     public synchronized void ensureCapacity(int minCapacity) {
   226         if (minCapacity > 0) {
   227             modCount++;
   228             ensureCapacityHelper(minCapacity);
   229         }
   230     }
   231 
   232     /**
   233      * This implements the unsynchronized semantics of ensureCapacity.
   234      * Synchronized methods in this class can internally call this
   235      * method for ensuring capacity without incurring the cost of an
   236      * extra synchronization.
   237      *
   238      * @see #ensureCapacity(int)
   239      */
   240     private void ensureCapacityHelper(int minCapacity) {
   241         // overflow-conscious code
   242         if (minCapacity - elementData.length > 0)
   243             grow(minCapacity);
   244     }
   245 
   246     /**
   247      * The maximum size of array to allocate.
   248      * Some VMs reserve some header words in an array.
   249      * Attempts to allocate larger arrays may result in
   250      * OutOfMemoryError: Requested array size exceeds VM limit
   251      */
   252     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
   253 
   254     private void grow(int minCapacity) {
   255         // overflow-conscious code
   256         int oldCapacity = elementData.length;
   257         int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
   258                                          capacityIncrement : oldCapacity);
   259         if (newCapacity - minCapacity < 0)
   260             newCapacity = minCapacity;
   261         if (newCapacity - MAX_ARRAY_SIZE > 0)
   262             newCapacity = hugeCapacity(minCapacity);
   263         elementData = Arrays.copyOf(elementData, newCapacity);
   264     }
   265 
   266     private static int hugeCapacity(int minCapacity) {
   267         if (minCapacity < 0) // overflow
   268             throw new OutOfMemoryError();
   269         return (minCapacity > MAX_ARRAY_SIZE) ?
   270             Integer.MAX_VALUE :
   271             MAX_ARRAY_SIZE;
   272     }
   273 
   274     /**
   275      * Sets the size of this vector. If the new size is greater than the
   276      * current size, new {@code null} items are added to the end of
   277      * the vector. If the new size is less than the current size, all
   278      * components at index {@code newSize} and greater are discarded.
   279      *
   280      * @param  newSize   the new size of this vector
   281      * @throws ArrayIndexOutOfBoundsException if the new size is negative
   282      */
   283     public synchronized void setSize(int newSize) {
   284         modCount++;
   285         if (newSize > elementCount) {
   286             ensureCapacityHelper(newSize);
   287         } else {
   288             for (int i = newSize ; i < elementCount ; i++) {
   289                 elementData[i] = null;
   290             }
   291         }
   292         elementCount = newSize;
   293     }
   294 
   295     /**
   296      * Returns the current capacity of this vector.
   297      *
   298      * @return  the current capacity (the length of its internal
   299      *          data array, kept in the field {@code elementData}
   300      *          of this vector)
   301      */
   302     public synchronized int capacity() {
   303         return elementData.length;
   304     }
   305 
   306     /**
   307      * Returns the number of components in this vector.
   308      *
   309      * @return  the number of components in this vector
   310      */
   311     public synchronized int size() {
   312         return elementCount;
   313     }
   314 
   315     /**
   316      * Tests if this vector has no components.
   317      *
   318      * @return  {@code true} if and only if this vector has
   319      *          no components, that is, its size is zero;
   320      *          {@code false} otherwise.
   321      */
   322     public synchronized boolean isEmpty() {
   323         return elementCount == 0;
   324     }
   325 
   326     /**
   327      * Returns an enumeration of the components of this vector. The
   328      * returned {@code Enumeration} object will generate all items in
   329      * this vector. The first item generated is the item at index {@code 0},
   330      * then the item at index {@code 1}, and so on.
   331      *
   332      * @return  an enumeration of the components of this vector
   333      * @see     Iterator
   334      */
   335     public Enumeration<E> elements() {
   336         return new Enumeration<E>() {
   337             int count = 0;
   338 
   339             public boolean hasMoreElements() {
   340                 return count < elementCount;
   341             }
   342 
   343             public E nextElement() {
   344                 synchronized (Vector.this) {
   345                     if (count < elementCount) {
   346                         return elementData(count++);
   347                     }
   348                 }
   349                 throw new NoSuchElementException("Vector Enumeration");
   350             }
   351         };
   352     }
   353 
   354     /**
   355      * Returns {@code true} if this vector contains the specified element.
   356      * More formally, returns {@code true} if and only if this vector
   357      * contains at least one element {@code e} such that
   358      * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
   359      *
   360      * @param o element whose presence in this vector is to be tested
   361      * @return {@code true} if this vector contains the specified element
   362      */
   363     public boolean contains(Object o) {
   364         return indexOf(o, 0) >= 0;
   365     }
   366 
   367     /**
   368      * Returns the index of the first occurrence of the specified element
   369      * in this vector, or -1 if this vector does not contain the element.
   370      * More formally, returns the lowest index {@code i} such that
   371      * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
   372      * or -1 if there is no such index.
   373      *
   374      * @param o element to search for
   375      * @return the index of the first occurrence of the specified element in
   376      *         this vector, or -1 if this vector does not contain the element
   377      */
   378     public int indexOf(Object o) {
   379         return indexOf(o, 0);
   380     }
   381 
   382     /**
   383      * Returns the index of the first occurrence of the specified element in
   384      * this vector, searching forwards from {@code index}, or returns -1 if
   385      * the element is not found.
   386      * More formally, returns the lowest index {@code i} such that
   387      * <tt>(i&nbsp;&gt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i))))</tt>,
   388      * or -1 if there is no such index.
   389      *
   390      * @param o element to search for
   391      * @param index index to start searching from
   392      * @return the index of the first occurrence of the element in
   393      *         this vector at position {@code index} or later in the vector;
   394      *         {@code -1} if the element is not found.
   395      * @throws IndexOutOfBoundsException if the specified index is negative
   396      * @see     Object#equals(Object)
   397      */
   398     public synchronized int indexOf(Object o, int index) {
   399         if (o == null) {
   400             for (int i = index ; i < elementCount ; i++)
   401                 if (elementData[i]==null)
   402                     return i;
   403         } else {
   404             for (int i = index ; i < elementCount ; i++)
   405                 if (o.equals(elementData[i]))
   406                     return i;
   407         }
   408         return -1;
   409     }
   410 
   411     /**
   412      * Returns the index of the last occurrence of the specified element
   413      * in this vector, or -1 if this vector does not contain the element.
   414      * More formally, returns the highest index {@code i} such that
   415      * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
   416      * or -1 if there is no such index.
   417      *
   418      * @param o element to search for
   419      * @return the index of the last occurrence of the specified element in
   420      *         this vector, or -1 if this vector does not contain the element
   421      */
   422     public synchronized int lastIndexOf(Object o) {
   423         return lastIndexOf(o, elementCount-1);
   424     }
   425 
   426     /**
   427      * Returns the index of the last occurrence of the specified element in
   428      * this vector, searching backwards from {@code index}, or returns -1 if
   429      * the element is not found.
   430      * More formally, returns the highest index {@code i} such that
   431      * <tt>(i&nbsp;&lt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i))))</tt>,
   432      * or -1 if there is no such index.
   433      *
   434      * @param o element to search for
   435      * @param index index to start searching backwards from
   436      * @return the index of the last occurrence of the element at position
   437      *         less than or equal to {@code index} in this vector;
   438      *         -1 if the element is not found.
   439      * @throws IndexOutOfBoundsException if the specified index is greater
   440      *         than or equal to the current size of this vector
   441      */
   442     public synchronized int lastIndexOf(Object o, int index) {
   443         if (index >= elementCount)
   444             throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
   445 
   446         if (o == null) {
   447             for (int i = index; i >= 0; i--)
   448                 if (elementData[i]==null)
   449                     return i;
   450         } else {
   451             for (int i = index; i >= 0; i--)
   452                 if (o.equals(elementData[i]))
   453                     return i;
   454         }
   455         return -1;
   456     }
   457 
   458     /**
   459      * Returns the component at the specified index.
   460      *
   461      * <p>This method is identical in functionality to the {@link #get(int)}
   462      * method (which is part of the {@link List} interface).
   463      *
   464      * @param      index   an index into this vector
   465      * @return     the component at the specified index
   466      * @throws ArrayIndexOutOfBoundsException if the index is out of range
   467      *         ({@code index < 0 || index >= size()})
   468      */
   469     public synchronized E elementAt(int index) {
   470         if (index >= elementCount) {
   471             throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
   472         }
   473 
   474         return elementData(index);
   475     }
   476 
   477     /**
   478      * Returns the first component (the item at index {@code 0}) of
   479      * this vector.
   480      *
   481      * @return     the first component of this vector
   482      * @throws NoSuchElementException if this vector has no components
   483      */
   484     public synchronized E firstElement() {
   485         if (elementCount == 0) {
   486             throw new NoSuchElementException();
   487         }
   488         return elementData(0);
   489     }
   490 
   491     /**
   492      * Returns the last component of the vector.
   493      *
   494      * @return  the last component of the vector, i.e., the component at index
   495      *          <code>size()&nbsp;-&nbsp;1</code>.
   496      * @throws NoSuchElementException if this vector is empty
   497      */
   498     public synchronized E lastElement() {
   499         if (elementCount == 0) {
   500             throw new NoSuchElementException();
   501         }
   502         return elementData(elementCount - 1);
   503     }
   504 
   505     /**
   506      * Sets the component at the specified {@code index} of this
   507      * vector to be the specified object. The previous component at that
   508      * position is discarded.
   509      *
   510      * <p>The index must be a value greater than or equal to {@code 0}
   511      * and less than the current size of the vector.
   512      *
   513      * <p>This method is identical in functionality to the
   514      * {@link #set(int, Object) set(int, E)}
   515      * method (which is part of the {@link List} interface). Note that the
   516      * {@code set} method reverses the order of the parameters, to more closely
   517      * match array usage.  Note also that the {@code set} method returns the
   518      * old value that was stored at the specified position.
   519      *
   520      * @param      obj     what the component is to be set to
   521      * @param      index   the specified index
   522      * @throws ArrayIndexOutOfBoundsException if the index is out of range
   523      *         ({@code index < 0 || index >= size()})
   524      */
   525     public synchronized void setElementAt(E obj, int index) {
   526         if (index >= elementCount) {
   527             throw new ArrayIndexOutOfBoundsException(index + " >= " +
   528                                                      elementCount);
   529         }
   530         elementData[index] = obj;
   531     }
   532 
   533     /**
   534      * Deletes the component at the specified index. Each component in
   535      * this vector with an index greater or equal to the specified
   536      * {@code index} is shifted downward to have an index one
   537      * smaller than the value it had previously. The size of this vector
   538      * is decreased by {@code 1}.
   539      *
   540      * <p>The index must be a value greater than or equal to {@code 0}
   541      * and less than the current size of the vector.
   542      *
   543      * <p>This method is identical in functionality to the {@link #remove(int)}
   544      * method (which is part of the {@link List} interface).  Note that the
   545      * {@code remove} method returns the old value that was stored at the
   546      * specified position.
   547      *
   548      * @param      index   the index of the object to remove
   549      * @throws ArrayIndexOutOfBoundsException if the index is out of range
   550      *         ({@code index < 0 || index >= size()})
   551      */
   552     public synchronized void removeElementAt(int index) {
   553         modCount++;
   554         if (index >= elementCount) {
   555             throw new ArrayIndexOutOfBoundsException(index + " >= " +
   556                                                      elementCount);
   557         }
   558         else if (index < 0) {
   559             throw new ArrayIndexOutOfBoundsException(index);
   560         }
   561         int j = elementCount - index - 1;
   562         if (j > 0) {
   563             System.arraycopy(elementData, index + 1, elementData, index, j);
   564         }
   565         elementCount--;
   566         elementData[elementCount] = null; /* to let gc do its work */
   567     }
   568 
   569     /**
   570      * Inserts the specified object as a component in this vector at the
   571      * specified {@code index}. Each component in this vector with
   572      * an index greater or equal to the specified {@code index} is
   573      * shifted upward to have an index one greater than the value it had
   574      * previously.
   575      *
   576      * <p>The index must be a value greater than or equal to {@code 0}
   577      * and less than or equal to the current size of the vector. (If the
   578      * index is equal to the current size of the vector, the new element
   579      * is appended to the Vector.)
   580      *
   581      * <p>This method is identical in functionality to the
   582      * {@link #add(int, Object) add(int, E)}
   583      * method (which is part of the {@link List} interface).  Note that the
   584      * {@code add} method reverses the order of the parameters, to more closely
   585      * match array usage.
   586      *
   587      * @param      obj     the component to insert
   588      * @param      index   where to insert the new component
   589      * @throws ArrayIndexOutOfBoundsException if the index is out of range
   590      *         ({@code index < 0 || index > size()})
   591      */
   592     public synchronized void insertElementAt(E obj, int index) {
   593         modCount++;
   594         if (index > elementCount) {
   595             throw new ArrayIndexOutOfBoundsException(index
   596                                                      + " > " + elementCount);
   597         }
   598         ensureCapacityHelper(elementCount + 1);
   599         System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
   600         elementData[index] = obj;
   601         elementCount++;
   602     }
   603 
   604     /**
   605      * Adds the specified component to the end of this vector,
   606      * increasing its size by one. The capacity of this vector is
   607      * increased if its size becomes greater than its capacity.
   608      *
   609      * <p>This method is identical in functionality to the
   610      * {@link #add(Object) add(E)}
   611      * method (which is part of the {@link List} interface).
   612      *
   613      * @param   obj   the component to be added
   614      */
   615     public synchronized void addElement(E obj) {
   616         modCount++;
   617         ensureCapacityHelper(elementCount + 1);
   618         elementData[elementCount++] = obj;
   619     }
   620 
   621     /**
   622      * Removes the first (lowest-indexed) occurrence of the argument
   623      * from this vector. If the object is found in this vector, each
   624      * component in the vector with an index greater or equal to the
   625      * object's index is shifted downward to have an index one smaller
   626      * than the value it had previously.
   627      *
   628      * <p>This method is identical in functionality to the
   629      * {@link #remove(Object)} method (which is part of the
   630      * {@link List} interface).
   631      *
   632      * @param   obj   the component to be removed
   633      * @return  {@code true} if the argument was a component of this
   634      *          vector; {@code false} otherwise.
   635      */
   636     public synchronized boolean removeElement(Object obj) {
   637         modCount++;
   638         int i = indexOf(obj);
   639         if (i >= 0) {
   640             removeElementAt(i);
   641             return true;
   642         }
   643         return false;
   644     }
   645 
   646     /**
   647      * Removes all components from this vector and sets its size to zero.
   648      *
   649      * <p>This method is identical in functionality to the {@link #clear}
   650      * method (which is part of the {@link List} interface).
   651      */
   652     public synchronized void removeAllElements() {
   653         modCount++;
   654         // Let gc do its work
   655         for (int i = 0; i < elementCount; i++)
   656             elementData[i] = null;
   657 
   658         elementCount = 0;
   659     }
   660 
   661     /**
   662      * Returns a clone of this vector. The copy will contain a
   663      * reference to a clone of the internal data array, not a reference
   664      * to the original internal data array of this {@code Vector} object.
   665      *
   666      * @return  a clone of this vector
   667      */
   668     public synchronized Object clone() {
   669         try {
   670             @SuppressWarnings("unchecked")
   671                 Vector<E> v = (Vector<E>) super.clone();
   672             v.elementData = Arrays.copyOf(elementData, elementCount);
   673             v.modCount = 0;
   674             return v;
   675         } catch (CloneNotSupportedException e) {
   676             // this shouldn't happen, since we are Cloneable
   677             throw new InternalError();
   678         }
   679     }
   680 
   681     /**
   682      * Returns an array containing all of the elements in this Vector
   683      * in the correct order.
   684      *
   685      * @since 1.2
   686      */
   687     public synchronized Object[] toArray() {
   688         return Arrays.copyOf(elementData, elementCount);
   689     }
   690 
   691     /**
   692      * Returns an array containing all of the elements in this Vector in the
   693      * correct order; the runtime type of the returned array is that of the
   694      * specified array.  If the Vector fits in the specified array, it is
   695      * returned therein.  Otherwise, a new array is allocated with the runtime
   696      * type of the specified array and the size of this Vector.
   697      *
   698      * <p>If the Vector fits in the specified array with room to spare
   699      * (i.e., the array has more elements than the Vector),
   700      * the element in the array immediately following the end of the
   701      * Vector is set to null.  (This is useful in determining the length
   702      * of the Vector <em>only</em> if the caller knows that the Vector
   703      * does not contain any null elements.)
   704      *
   705      * @param a the array into which the elements of the Vector are to
   706      *          be stored, if it is big enough; otherwise, a new array of the
   707      *          same runtime type is allocated for this purpose.
   708      * @return an array containing the elements of the Vector
   709      * @throws ArrayStoreException if the runtime type of a is not a supertype
   710      * of the runtime type of every element in this Vector
   711      * @throws NullPointerException if the given array is null
   712      * @since 1.2
   713      */
   714     @SuppressWarnings("unchecked")
   715     public synchronized <T> T[] toArray(T[] a) {
   716         if (a.length < elementCount)
   717             return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
   718 
   719         System.arraycopy(elementData, 0, a, 0, elementCount);
   720 
   721         if (a.length > elementCount)
   722             a[elementCount] = null;
   723 
   724         return a;
   725     }
   726 
   727     // Positional Access Operations
   728 
   729     @SuppressWarnings("unchecked")
   730     E elementData(int index) {
   731         return (E) elementData[index];
   732     }
   733 
   734     /**
   735      * Returns the element at the specified position in this Vector.
   736      *
   737      * @param index index of the element to return
   738      * @return object at the specified index
   739      * @throws ArrayIndexOutOfBoundsException if the index is out of range
   740      *            ({@code index < 0 || index >= size()})
   741      * @since 1.2
   742      */
   743     public synchronized E get(int index) {
   744         if (index >= elementCount)
   745             throw new ArrayIndexOutOfBoundsException(index);
   746 
   747         return elementData(index);
   748     }
   749 
   750     /**
   751      * Replaces the element at the specified position in this Vector with the
   752      * specified element.
   753      *
   754      * @param index index of the element to replace
   755      * @param element element to be stored at the specified position
   756      * @return the element previously at the specified position
   757      * @throws ArrayIndexOutOfBoundsException if the index is out of range
   758      *         ({@code index < 0 || index >= size()})
   759      * @since 1.2
   760      */
   761     public synchronized E set(int index, E element) {
   762         if (index >= elementCount)
   763             throw new ArrayIndexOutOfBoundsException(index);
   764 
   765         E oldValue = elementData(index);
   766         elementData[index] = element;
   767         return oldValue;
   768     }
   769 
   770     /**
   771      * Appends the specified element to the end of this Vector.
   772      *
   773      * @param e element to be appended to this Vector
   774      * @return {@code true} (as specified by {@link Collection#add})
   775      * @since 1.2
   776      */
   777     public synchronized boolean add(E e) {
   778         modCount++;
   779         ensureCapacityHelper(elementCount + 1);
   780         elementData[elementCount++] = e;
   781         return true;
   782     }
   783 
   784     /**
   785      * Removes the first occurrence of the specified element in this Vector
   786      * If the Vector does not contain the element, it is unchanged.  More
   787      * formally, removes the element with the lowest index i such that
   788      * {@code (o==null ? get(i)==null : o.equals(get(i)))} (if such
   789      * an element exists).
   790      *
   791      * @param o element to be removed from this Vector, if present
   792      * @return true if the Vector contained the specified element
   793      * @since 1.2
   794      */
   795     public boolean remove(Object o) {
   796         return removeElement(o);
   797     }
   798 
   799     /**
   800      * Inserts the specified element at the specified position in this Vector.
   801      * Shifts the element currently at that position (if any) and any
   802      * subsequent elements to the right (adds one to their indices).
   803      *
   804      * @param index index at which the specified element is to be inserted
   805      * @param element element to be inserted
   806      * @throws ArrayIndexOutOfBoundsException if the index is out of range
   807      *         ({@code index < 0 || index > size()})
   808      * @since 1.2
   809      */
   810     public void add(int index, E element) {
   811         insertElementAt(element, index);
   812     }
   813 
   814     /**
   815      * Removes the element at the specified position in this Vector.
   816      * Shifts any subsequent elements to the left (subtracts one from their
   817      * indices).  Returns the element that was removed from the Vector.
   818      *
   819      * @throws ArrayIndexOutOfBoundsException if the index is out of range
   820      *         ({@code index < 0 || index >= size()})
   821      * @param index the index of the element to be removed
   822      * @return element that was removed
   823      * @since 1.2
   824      */
   825     public synchronized E remove(int index) {
   826         modCount++;
   827         if (index >= elementCount)
   828             throw new ArrayIndexOutOfBoundsException(index);
   829         E oldValue = elementData(index);
   830 
   831         int numMoved = elementCount - index - 1;
   832         if (numMoved > 0)
   833             System.arraycopy(elementData, index+1, elementData, index,
   834                              numMoved);
   835         elementData[--elementCount] = null; // Let gc do its work
   836 
   837         return oldValue;
   838     }
   839 
   840     /**
   841      * Removes all of the elements from this Vector.  The Vector will
   842      * be empty after this call returns (unless it throws an exception).
   843      *
   844      * @since 1.2
   845      */
   846     public void clear() {
   847         removeAllElements();
   848     }
   849 
   850     // Bulk Operations
   851 
   852     /**
   853      * Returns true if this Vector contains all of the elements in the
   854      * specified Collection.
   855      *
   856      * @param   c a collection whose elements will be tested for containment
   857      *          in this Vector
   858      * @return true if this Vector contains all of the elements in the
   859      *         specified collection
   860      * @throws NullPointerException if the specified collection is null
   861      */
   862     public synchronized boolean containsAll(Collection<?> c) {
   863         return super.containsAll(c);
   864     }
   865 
   866     /**
   867      * Appends all of the elements in the specified Collection to the end of
   868      * this Vector, in the order that they are returned by the specified
   869      * Collection's Iterator.  The behavior of this operation is undefined if
   870      * the specified Collection is modified while the operation is in progress.
   871      * (This implies that the behavior of this call is undefined if the
   872      * specified Collection is this Vector, and this Vector is nonempty.)
   873      *
   874      * @param c elements to be inserted into this Vector
   875      * @return {@code true} if this Vector changed as a result of the call
   876      * @throws NullPointerException if the specified collection is null
   877      * @since 1.2
   878      */
   879     public synchronized boolean addAll(Collection<? extends E> c) {
   880         modCount++;
   881         Object[] a = c.toArray();
   882         int numNew = a.length;
   883         ensureCapacityHelper(elementCount + numNew);
   884         System.arraycopy(a, 0, elementData, elementCount, numNew);
   885         elementCount += numNew;
   886         return numNew != 0;
   887     }
   888 
   889     /**
   890      * Removes from this Vector all of its elements that are contained in the
   891      * specified Collection.
   892      *
   893      * @param c a collection of elements to be removed from the Vector
   894      * @return true if this Vector changed as a result of the call
   895      * @throws ClassCastException if the types of one or more elements
   896      *         in this vector are incompatible with the specified
   897      *         collection
   898      * (<a href="Collection.html#optional-restrictions">optional</a>)
   899      * @throws NullPointerException if this vector contains one or more null
   900      *         elements and the specified collection does not support null
   901      *         elements
   902      * (<a href="Collection.html#optional-restrictions">optional</a>),
   903      *         or if the specified collection is null
   904      * @since 1.2
   905      */
   906     public synchronized boolean removeAll(Collection<?> c) {
   907         return super.removeAll(c);
   908     }
   909 
   910     /**
   911      * Retains only the elements in this Vector that are contained in the
   912      * specified Collection.  In other words, removes from this Vector all
   913      * of its elements that are not contained in the specified Collection.
   914      *
   915      * @param c a collection of elements to be retained in this Vector
   916      *          (all other elements are removed)
   917      * @return true if this Vector changed as a result of the call
   918      * @throws ClassCastException if the types of one or more elements
   919      *         in this vector are incompatible with the specified
   920      *         collection
   921      * (<a href="Collection.html#optional-restrictions">optional</a>)
   922      * @throws NullPointerException if this vector contains one or more null
   923      *         elements and the specified collection does not support null
   924      *         elements
   925      *         (<a href="Collection.html#optional-restrictions">optional</a>),
   926      *         or if the specified collection is null
   927      * @since 1.2
   928      */
   929     public synchronized boolean retainAll(Collection<?> c) {
   930         return super.retainAll(c);
   931     }
   932 
   933     /**
   934      * Inserts all of the elements in the specified Collection into this
   935      * Vector at the specified position.  Shifts the element currently at
   936      * that position (if any) and any subsequent elements to the right
   937      * (increases their indices).  The new elements will appear in the Vector
   938      * in the order that they are returned by the specified Collection's
   939      * iterator.
   940      *
   941      * @param index index at which to insert the first element from the
   942      *              specified collection
   943      * @param c elements to be inserted into this Vector
   944      * @return {@code true} if this Vector changed as a result of the call
   945      * @throws ArrayIndexOutOfBoundsException if the index is out of range
   946      *         ({@code index < 0 || index > size()})
   947      * @throws NullPointerException if the specified collection is null
   948      * @since 1.2
   949      */
   950     public synchronized boolean addAll(int index, Collection<? extends E> c) {
   951         modCount++;
   952         if (index < 0 || index > elementCount)
   953             throw new ArrayIndexOutOfBoundsException(index);
   954 
   955         Object[] a = c.toArray();
   956         int numNew = a.length;
   957         ensureCapacityHelper(elementCount + numNew);
   958 
   959         int numMoved = elementCount - index;
   960         if (numMoved > 0)
   961             System.arraycopy(elementData, index, elementData, index + numNew,
   962                              numMoved);
   963 
   964         System.arraycopy(a, 0, elementData, index, numNew);
   965         elementCount += numNew;
   966         return numNew != 0;
   967     }
   968 
   969     /**
   970      * Compares the specified Object with this Vector for equality.  Returns
   971      * true if and only if the specified Object is also a List, both Lists
   972      * have the same size, and all corresponding pairs of elements in the two
   973      * Lists are <em>equal</em>.  (Two elements {@code e1} and
   974      * {@code e2} are <em>equal</em> if {@code (e1==null ? e2==null :
   975      * e1.equals(e2))}.)  In other words, two Lists are defined to be
   976      * equal if they contain the same elements in the same order.
   977      *
   978      * @param o the Object to be compared for equality with this Vector
   979      * @return true if the specified Object is equal to this Vector
   980      */
   981     public synchronized boolean equals(Object o) {
   982         return super.equals(o);
   983     }
   984 
   985     /**
   986      * Returns the hash code value for this Vector.
   987      */
   988     public synchronized int hashCode() {
   989         return super.hashCode();
   990     }
   991 
   992     /**
   993      * Returns a string representation of this Vector, containing
   994      * the String representation of each element.
   995      */
   996     public synchronized String toString() {
   997         return super.toString();
   998     }
   999 
  1000     /**
  1001      * Returns a view of the portion of this List between fromIndex,
  1002      * inclusive, and toIndex, exclusive.  (If fromIndex and toIndex are
  1003      * equal, the returned List is empty.)  The returned List is backed by this
  1004      * List, so changes in the returned List are reflected in this List, and
  1005      * vice-versa.  The returned List supports all of the optional List
  1006      * operations supported by this List.
  1007      *
  1008      * <p>This method eliminates the need for explicit range operations (of
  1009      * the sort that commonly exist for arrays).  Any operation that expects
  1010      * a List can be used as a range operation by operating on a subList view
  1011      * instead of a whole List.  For example, the following idiom
  1012      * removes a range of elements from a List:
  1013      * <pre>
  1014      *      list.subList(from, to).clear();
  1015      * </pre>
  1016      * Similar idioms may be constructed for indexOf and lastIndexOf,
  1017      * and all of the algorithms in the Collections class can be applied to
  1018      * a subList.
  1019      *
  1020      * <p>The semantics of the List returned by this method become undefined if
  1021      * the backing list (i.e., this List) is <i>structurally modified</i> in
  1022      * any way other than via the returned List.  (Structural modifications are
  1023      * those that change the size of the List, or otherwise perturb it in such
  1024      * a fashion that iterations in progress may yield incorrect results.)
  1025      *
  1026      * @param fromIndex low endpoint (inclusive) of the subList
  1027      * @param toIndex high endpoint (exclusive) of the subList
  1028      * @return a view of the specified range within this List
  1029      * @throws IndexOutOfBoundsException if an endpoint index value is out of range
  1030      *         {@code (fromIndex < 0 || toIndex > size)}
  1031      * @throws IllegalArgumentException if the endpoint indices are out of order
  1032      *         {@code (fromIndex > toIndex)}
  1033      */
  1034     public synchronized List<E> subList(int fromIndex, int toIndex) {
  1035         return Collections.synchronizedList(super.subList(fromIndex, toIndex),
  1036                                             this);
  1037     }
  1038 
  1039     /**
  1040      * Removes from this list all of the elements whose index is between
  1041      * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
  1042      * Shifts any succeeding elements to the left (reduces their index).
  1043      * This call shortens the list by {@code (toIndex - fromIndex)} elements.
  1044      * (If {@code toIndex==fromIndex}, this operation has no effect.)
  1045      */
  1046     protected synchronized void removeRange(int fromIndex, int toIndex) {
  1047         modCount++;
  1048         int numMoved = elementCount - toIndex;
  1049         System.arraycopy(elementData, toIndex, elementData, fromIndex,
  1050                          numMoved);
  1051 
  1052         // Let gc do its work
  1053         int newElementCount = elementCount - (toIndex-fromIndex);
  1054         while (elementCount != newElementCount)
  1055             elementData[--elementCount] = null;
  1056     }
  1057 
  1058     /**
  1059      * Returns a list iterator over the elements in this list (in proper
  1060      * sequence), starting at the specified position in the list.
  1061      * The specified index indicates the first element that would be
  1062      * returned by an initial call to {@link ListIterator#next next}.
  1063      * An initial call to {@link ListIterator#previous previous} would
  1064      * return the element with the specified index minus one.
  1065      *
  1066      * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
  1067      *
  1068      * @throws IndexOutOfBoundsException {@inheritDoc}
  1069      */
  1070     public synchronized ListIterator<E> listIterator(int index) {
  1071         if (index < 0 || index > elementCount)
  1072             throw new IndexOutOfBoundsException("Index: "+index);
  1073         return new ListItr(index);
  1074     }
  1075 
  1076     /**
  1077      * Returns a list iterator over the elements in this list (in proper
  1078      * sequence).
  1079      *
  1080      * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
  1081      *
  1082      * @see #listIterator(int)
  1083      */
  1084     public synchronized ListIterator<E> listIterator() {
  1085         return new ListItr(0);
  1086     }
  1087 
  1088     /**
  1089      * Returns an iterator over the elements in this list in proper sequence.
  1090      *
  1091      * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
  1092      *
  1093      * @return an iterator over the elements in this list in proper sequence
  1094      */
  1095     public synchronized Iterator<E> iterator() {
  1096         return new Itr();
  1097     }
  1098 
  1099     /**
  1100      * An optimized version of AbstractList.Itr
  1101      */
  1102     private class Itr implements Iterator<E> {
  1103         int cursor;       // index of next element to return
  1104         int lastRet = -1; // index of last element returned; -1 if no such
  1105         int expectedModCount = modCount;
  1106 
  1107         public boolean hasNext() {
  1108             // Racy but within spec, since modifications are checked
  1109             // within or after synchronization in next/previous
  1110             return cursor != elementCount;
  1111         }
  1112 
  1113         public E next() {
  1114             synchronized (Vector.this) {
  1115                 checkForComodification();
  1116                 int i = cursor;
  1117                 if (i >= elementCount)
  1118                     throw new NoSuchElementException();
  1119                 cursor = i + 1;
  1120                 return elementData(lastRet = i);
  1121             }
  1122         }
  1123 
  1124         public void remove() {
  1125             if (lastRet == -1)
  1126                 throw new IllegalStateException();
  1127             synchronized (Vector.this) {
  1128                 checkForComodification();
  1129                 Vector.this.remove(lastRet);
  1130                 expectedModCount = modCount;
  1131             }
  1132             cursor = lastRet;
  1133             lastRet = -1;
  1134         }
  1135 
  1136         final void checkForComodification() {
  1137             if (modCount != expectedModCount)
  1138                 throw new ConcurrentModificationException();
  1139         }
  1140     }
  1141 
  1142     /**
  1143      * An optimized version of AbstractList.ListItr
  1144      */
  1145     final class ListItr extends Itr implements ListIterator<E> {
  1146         ListItr(int index) {
  1147             super();
  1148             cursor = index;
  1149         }
  1150 
  1151         public boolean hasPrevious() {
  1152             return cursor != 0;
  1153         }
  1154 
  1155         public int nextIndex() {
  1156             return cursor;
  1157         }
  1158 
  1159         public int previousIndex() {
  1160             return cursor - 1;
  1161         }
  1162 
  1163         public E previous() {
  1164             synchronized (Vector.this) {
  1165                 checkForComodification();
  1166                 int i = cursor - 1;
  1167                 if (i < 0)
  1168                     throw new NoSuchElementException();
  1169                 cursor = i;
  1170                 return elementData(lastRet = i);
  1171             }
  1172         }
  1173 
  1174         public void set(E e) {
  1175             if (lastRet == -1)
  1176                 throw new IllegalStateException();
  1177             synchronized (Vector.this) {
  1178                 checkForComodification();
  1179                 Vector.this.set(lastRet, e);
  1180             }
  1181         }
  1182 
  1183         public void add(E e) {
  1184             int i = cursor;
  1185             synchronized (Vector.this) {
  1186                 checkForComodification();
  1187                 Vector.this.add(i, e);
  1188                 expectedModCount = modCount;
  1189             }
  1190             cursor = i + 1;
  1191             lastRet = -1;
  1192         }
  1193     }
  1194 }