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