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