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