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