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