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