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