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