1 /*
2  * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */

25
26 package java.util;
27
28 import java.io.IOException;
29 import java.io.ObjectInputStream;
30 import java.io.StreamCorruptedException;
31 import java.util.function.Consumer;
32 import java.util.function.Predicate;
33 import java.util.function.UnaryOperator;
34
35 /**
36  * The {@code Vector} class implements a growable array of
37  * objects. Like an array, it contains components that can be
38  * accessed using an integer index. However, the size of a
39  * {@code Vector} can grow or shrink as needed to accommodate
40  * adding and removing items after the {@code Vector} has been created.
41  *
42  * <p>Each vector tries to optimize storage management by maintaining a
43  * {@code capacity} and a {@code capacityIncrement}. The
44  * {@code capacity} is always at least as large as the vector
45  * size; it is usually larger because as components are added to the
46  * vector, the vector's storage increases in chunks the size of
47  * {@code capacityIncrement}. An application can increase the
48  * capacity of a vector before inserting a large number of
49  * components; this reduces the amount of incremental reallocation.
50  *
51  * <p id="fail-fast">
52  * The iterators returned by this class's {@link #iterator() iterator} and
53  * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
54  * if the vector is structurally modified at any time after the iterator is
55  * created, in any way except through the iterator's own
56  * {@link ListIterator#remove() remove} or
57  * {@link ListIterator#add(Object) add} methods, the iterator will throw a
58  * {@link ConcurrentModificationException}.  Thus, in the face of
59  * concurrent modification, the iterator fails quickly and cleanly, rather
60  * than risking arbitrary, non-deterministic behavior at an undetermined
61  * time in the future.  The {@link Enumeration Enumerations} returned by
62  * the {@link #elements() elements} method are <em>not</em> fail-fast; if the
63  * Vector is structurally modified at any time after the enumeration is
64  * created then the results of enumerating are undefined.
65  *
66  * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
67  * as it is, generally speaking, impossible to make any hard guarantees in the
68  * presence of unsynchronized concurrent modification.  Fail-fast iterators
69  * throw {@code ConcurrentModificationException} on a best-effort basis.
70  * Therefore, it would be wrong to write a program that depended on this
71  * exception for its correctness:  <i>the fail-fast behavior of iterators
72  * should be used only to detect bugs.</i>
73  *
74  * <p>As of the Java 2 platform v1.2, this class was retrofitted to
75  * implement the {@link List} interface, making it a member of the
76  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
77  * Java Collections Framework</a>.  Unlike the new collection
78  * implementations, {@code Vector} is synchronized.  If a thread-safe
79  * implementation is not needed, it is recommended to use {@link
80  * ArrayList} in place of {@code Vector}.
81  *
82  * @param <E> Type of component elements
83  *
84  * @author  Lee Boynton
85  * @author  Jonathan Payne
86  * @see Collection
87  * @see LinkedList
88  * @since   1.0
89  */

90 public class Vector<E>
91     extends AbstractList<E>
92     implements List<E>, RandomAccess, Cloneable, java.io.Serializable
93 {
94     /**
95      * The array buffer into which the components of the vector are
96      * stored. The capacity of the vector is the length of this array buffer,
97      * and is at least large enough to contain all the vector's elements.
98      *
99      * <p>Any array elements following the last element in the Vector are null.
100      *
101      * @serial
102      */

103     protected Object[] elementData;
104
105     /**
106      * The number of valid components in this {@code Vector} object.
107      * Components {@code elementData[0]} through
108      * {@code elementData[elementCount-1]} are the actual items.
109      *
110      * @serial
111      */

112     protected int elementCount;
113
114     /**
115      * The amount by which the capacity of the vector is automatically
116      * incremented when its size becomes greater than its capacity.  If
117      * the capacity increment is less than or equal to zero, the capacity
118      * of the vector is doubled each time it needs to grow.
119      *
120      * @serial
121      */

122     protected int capacityIncrement;
123
124     /** use serialVersionUID from JDK 1.0.2 for interoperability */
125     private static final long serialVersionUID = -2767605614048989439L;
126
127     /**
128      * Constructs an empty vector with the specified initial capacity and
129      * capacity increment.
130      *
131      * @param   initialCapacity     the initial capacity of the vector
132      * @param   capacityIncrement   the amount by which the capacity is
133      *                              increased when the vector overflows
134      * @throws IllegalArgumentException if the specified initial capacity
135      *         is negative
136      */

137     public Vector(int initialCapacity, int capacityIncrement) {
138         super();
139         if (initialCapacity < 0)
140             throw new IllegalArgumentException("Illegal Capacity: "+
141                                                initialCapacity);
142         this.elementData = new Object[initialCapacity];
143         this.capacityIncrement = capacityIncrement;
144     }
145
146     /**
147      * Constructs an empty vector with the specified initial capacity and
148      * with its capacity increment equal to zero.
149      *
150      * @param   initialCapacity   the initial capacity of the vector
151      * @throws IllegalArgumentException if the specified initial capacity
152      *         is negative
153      */

154     public Vector(int initialCapacity) {
155         this(initialCapacity, 0);
156     }
157
158     /**
159      * Constructs an empty vector so that its internal data array
160      * has size {@code 10} and its standard capacity increment is
161      * zero.
162      */

163     public Vector() {
164         this(10);
165     }
166
167     /**
168      * Constructs a vector containing the elements of the specified
169      * collection, in the order they are returned by the collection's
170      * iterator.
171      *
172      * @param c the collection whose elements are to be placed into this
173      *       vector
174      * @throws NullPointerException if the specified collection is null
175      * @since   1.2
176      */

177     public Vector(Collection<? extends E> c) {
178         elementData = c.toArray();
179         elementCount = elementData.length;
180         // defend against c.toArray (incorrectly) not returning Object[]
181         // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
182         if (elementData.getClass() != Object[].class)
183             elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
184     }
185
186     /**
187      * Copies the components of this vector into the specified array.
188      * The item at index {@code k} in this vector is copied into
189      * component {@code k} of {@code anArray}.
190      *
191      * @param  anArray the array into which the components get copied
192      * @throws NullPointerException if the given array is null
193      * @throws IndexOutOfBoundsException if the specified array is not
194      *         large enough to hold all the components of this vector
195      * @throws ArrayStoreException if a component of this vector is not of
196      *         a runtime type that can be stored in the specified array
197      * @see #toArray(Object[])
198      */

199     public synchronized void copyInto(Object[] anArray) {
200         System.arraycopy(elementData, 0, anArray, 0, elementCount);
201     }
202
203     /**
204      * Trims the capacity of this vector to be the vector's current
205      * size. If the capacity of this vector is larger than its current
206      * size, then the capacity is changed to equal the size by replacing
207      * its internal data array, kept in the field {@code elementData},
208      * with a smaller one. An application can use this operation to
209      * minimize the storage of a vector.
210      */

211     public synchronized void trimToSize() {
212         modCount++;
213         int oldCapacity = elementData.length;
214         if (elementCount < oldCapacity) {
215             elementData = Arrays.copyOf(elementData, elementCount);
216         }
217     }
218
219     /**
220      * Increases the capacity of this vector, if necessary, to ensure
221      * that it can hold at least the number of components specified by
222      * the minimum capacity argument.
223      *
224      * <p>If the current capacity of this vector is less than
225      * {@code minCapacity}, then its capacity is increased by replacing its
226      * internal data array, kept in the field {@code elementData}, with a
227      * larger one.  The size of the new data array will be the old size plus
228      * {@code capacityIncrement}, unless the value of
229      * {@code capacityIncrement} is less than or equal to zero, in which case
230      * the new capacity will be twice the old capacity; but if this new size
231      * is still smaller than {@code minCapacity}, then the new capacity will
232      * be {@code minCapacity}.
233      *
234      * @param minCapacity the desired minimum capacity
235      */

236     public synchronized void ensureCapacity(int minCapacity) {
237         if (minCapacity > 0) {
238             modCount++;
239             if (minCapacity > elementData.length)
240                 grow(minCapacity);
241         }
242     }
243
244     /**
245      * The maximum size of array to allocate (unless necessary).
246      * Some VMs reserve some header words in an array.
247      * Attempts to allocate larger arrays may result in
248      * OutOfMemoryError: Requested array size exceeds VM limit
249      */

250     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
251
252     /**
253      * Increases the capacity to ensure that it can hold at least the
254      * number of elements specified by the minimum capacity argument.
255      *
256      * @param minCapacity the desired minimum capacity
257      * @throws OutOfMemoryError if minCapacity is less than zero
258      */

259     private Object[] grow(int minCapacity) {
260         return elementData = Arrays.copyOf(elementData,
261                                            newCapacity(minCapacity));
262     }
263
264     private Object[] grow() {
265         return grow(elementCount + 1);
266     }
267
268     /**
269      * Returns a capacity at least as large as the given minimum capacity.
270      * Will not return a capacity greater than MAX_ARRAY_SIZE unless
271      * the given minimum capacity is greater than MAX_ARRAY_SIZE.
272      *
273      * @param minCapacity the desired minimum capacity
274      * @throws OutOfMemoryError if minCapacity is less than zero
275      */

276     private int newCapacity(int minCapacity) {
277         // overflow-conscious code
278         int oldCapacity = elementData.length;
279         int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
280                                          capacityIncrement : oldCapacity);
281         if (newCapacity - minCapacity <= 0) {
282             if (minCapacity < 0) // overflow
283                 throw new OutOfMemoryError();
284             return minCapacity;
285         }
286         return (newCapacity - MAX_ARRAY_SIZE <= 0)
287             ? newCapacity
288             : hugeCapacity(minCapacity);
289     }
290
291     private static int hugeCapacity(int minCapacity) {
292         if (minCapacity < 0) // overflow
293             throw new OutOfMemoryError();
294         return (minCapacity > MAX_ARRAY_SIZE) ?
295             Integer.MAX_VALUE :
296             MAX_ARRAY_SIZE;
297     }
298
299     /**
300      * Sets the size of this vector. If the new size is greater than the
301      * current size, new {@code null} items are added to the end of
302      * the vector. If the new size is less than the current size, all
303      * components at index {@code newSize} and greater are discarded.
304      *
305      * @param  newSize   the new size of this vector
306      * @throws ArrayIndexOutOfBoundsException if the new size is negative
307      */

308     public synchronized void setSize(int newSize) {
309         modCount++;
310         if (newSize > elementData.length)
311             grow(newSize);
312         final Object[] es = elementData;
313         for (int to = elementCount, i = newSize; i < to; i++)
314             es[i] = null;
315         elementCount = newSize;
316     }
317
318     /**
319      * Returns the current capacity of this vector.
320      *
321      * @return  the current capacity (the length of its internal
322      *          data array, kept in the field {@code elementData}
323      *          of this vector)
324      */

325     public synchronized int capacity() {
326         return elementData.length;
327     }
328
329     /**
330      * Returns the number of components in this vector.
331      *
332      * @return  the number of components in this vector
333      */

334     public synchronized int size() {
335         return elementCount;
336     }
337
338     /**
339      * Tests if this vector has no components.
340      *
341      * @return  {@code trueif and only if this vector has
342      *          no components, that is, its size is zero;
343      *          {@code false} otherwise.
344      */

345     public synchronized boolean isEmpty() {
346         return elementCount == 0;
347     }
348
349     /**
350      * Returns an enumeration of the components of this vector. The
351      * returned {@code Enumeration} object will generate all items in
352      * this vector. The first item generated is the item at index {@code 0},
353      * then the item at index {@code 1}, and so on. If the vector is
354      * structurally modified while enumerating over the elements then the
355      * results of enumerating are undefined.
356      *
357      * @return  an enumeration of the components of this vector
358      * @see     Iterator
359      */

360     public Enumeration<E> elements() {
361         return new Enumeration<E>() {
362             int count = 0;
363
364             public boolean hasMoreElements() {
365                 return count < elementCount;
366             }
367
368             public E nextElement() {
369                 synchronized (Vector.this) {
370                     if (count < elementCount) {
371                         return elementData(count++);
372                     }
373                 }
374                 throw new NoSuchElementException("Vector Enumeration");
375             }
376         };
377     }
378
379     /**
380      * Returns {@code trueif this vector contains the specified element.
381      * More formally, returns {@code trueif and only if this vector
382      * contains at least one element {@code e} such that
383      * {@code Objects.equals(o, e)}.
384      *
385      * @param o element whose presence in this vector is to be tested
386      * @return {@code trueif this vector contains the specified element
387      */

388     public boolean contains(Object o) {
389         return indexOf(o, 0) >= 0;
390     }
391
392     /**
393      * Returns the index of the first occurrence of the specified element
394      * in this vector, or -1 if this vector does not contain the element.
395      * More formally, returns the lowest index {@code i} such that
396      * {@code Objects.equals(o, get(i))},
397      * or -1 if there is no such index.
398      *
399      * @param o element to search for
400      * @return the index of the first occurrence of the specified element in
401      *         this vector, or -1 if this vector does not contain the element
402      */

403     public int indexOf(Object o) {
404         return indexOf(o, 0);
405     }
406
407     /**
408      * Returns the index of the first occurrence of the specified element in
409      * this vector, searching forwards from {@code index}, or returns -1 if
410      * the element is not found.
411      * More formally, returns the lowest index {@code i} such that
412      * {@code (i >= index && Objects.equals(o, get(i)))},
413      * or -1 if there is no such index.
414      *
415      * @param o element to search for
416      * @param index index to start searching from
417      * @return the index of the first occurrence of the element in
418      *         this vector at position {@code index} or later in the vector;
419      *         {@code -1} if the element is not found.
420      * @throws IndexOutOfBoundsException if the specified index is negative
421      * @see     Object#equals(Object)
422      */

423     public synchronized int indexOf(Object o, int index) {
424         if (o == null) {
425             for (int i = index ; i < elementCount ; i++)
426                 if (elementData[i]==null)
427                     return i;
428         } else {
429             for (int i = index ; i < elementCount ; i++)
430                 if (o.equals(elementData[i]))
431                     return i;
432         }
433         return -1;
434     }
435
436     /**
437      * Returns the index of the last occurrence of the specified element
438      * in this vector, or -1 if this vector does not contain the element.
439      * More formally, returns the highest index {@code i} such that
440      * {@code Objects.equals(o, get(i))},
441      * or -1 if there is no such index.
442      *
443      * @param o element to search for
444      * @return the index of the last occurrence of the specified element in
445      *         this vector, or -1 if this vector does not contain the element
446      */

447     public synchronized int lastIndexOf(Object o) {
448         return lastIndexOf(o, elementCount-1);
449     }
450
451     /**
452      * Returns the index of the last occurrence of the specified element in
453      * this vector, searching backwards from {@code index}, or returns -1 if
454      * the element is not found.
455      * More formally, returns the highest index {@code i} such that
456      * {@code (i <= index && Objects.equals(o, get(i)))},
457      * or -1 if there is no such index.
458      *
459      * @param o element to search for
460      * @param index index to start searching backwards from
461      * @return the index of the last occurrence of the element at position
462      *         less than or equal to {@code index} in this vector;
463      *         -1 if the element is not found.
464      * @throws IndexOutOfBoundsException if the specified index is greater
465      *         than or equal to the current size of this vector
466      */

467     public synchronized int lastIndexOf(Object o, int index) {
468         if (index >= elementCount)
469             throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
470
471         if (o == null) {
472             for (int i = index; i >= 0; i--)
473                 if (elementData[i]==null)
474                     return i;
475         } else {
476             for (int i = index; i >= 0; i--)
477                 if (o.equals(elementData[i]))
478                     return i;
479         }
480         return -1;
481     }
482
483     /**
484      * Returns the component at the specified index.
485      *
486      * <p>This method is identical in functionality to the {@link #get(int)}
487      * method (which is part of the {@link List} interface).
488      *
489      * @param      index   an index into this vector
490      * @return     the component at the specified index
491      * @throws ArrayIndexOutOfBoundsException if the index is out of range
492      *         ({@code index < 0 || index >= size()})
493      */

494     public synchronized E elementAt(int index) {
495         if (index >= elementCount) {
496             throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
497         }
498
499         return elementData(index);
500     }
501
502     /**
503      * Returns the first component (the item at index {@code 0}) of
504      * this vector.
505      *
506      * @return     the first component of this vector
507      * @throws NoSuchElementException if this vector has no components
508      */

509     public synchronized E firstElement() {
510         if (elementCount == 0) {
511             throw new NoSuchElementException();
512         }
513         return elementData(0);
514     }
515
516     /**
517      * Returns the last component of the vector.
518      *
519      * @return  the last component of the vector, i.e., the component at index
520      *          {@code size() - 1}
521      * @throws NoSuchElementException if this vector is empty
522      */

523     public synchronized E lastElement() {
524         if (elementCount == 0) {
525             throw new NoSuchElementException();
526         }
527         return elementData(elementCount - 1);
528     }
529
530     /**
531      * Sets the component at the specified {@code index} of this
532      * vector to be the specified object. The previous component at that
533      * position is discarded.
534      *
535      * <p>The index must be a value greater than or equal to {@code 0}
536      * and less than the current size of the vector.
537      *
538      * <p>This method is identical in functionality to the
539      * {@link #set(int, Object) set(int, E)}
540      * method (which is part of the {@link List} interface). Note that the
541      * {@code set} method reverses the order of the parameters, to more closely
542      * match array usage.  Note also that the {@code set} method returns the
543      * old value that was stored at the specified position.
544      *
545      * @param      obj     what the component is to be set to
546      * @param      index   the specified index
547      * @throws ArrayIndexOutOfBoundsException if the index is out of range
548      *         ({@code index < 0 || index >= size()})
549      */

550     public synchronized void setElementAt(E obj, int index) {
551         if (index >= elementCount) {
552             throw new ArrayIndexOutOfBoundsException(index + " >= " +
553                                                      elementCount);
554         }
555         elementData[index] = obj;
556     }
557
558     /**
559      * Deletes the component at the specified index. Each component in
560      * this vector with an index greater or equal to the specified
561      * {@code index} is shifted downward to have an index one
562      * smaller than the value it had previously. The size of this vector
563      * is decreased by {@code 1}.
564      *
565      * <p>The index must be a value greater than or equal to {@code 0}
566      * and less than the current size of the vector.
567      *
568      * <p>This method is identical in functionality to the {@link #remove(int)}
569      * method (which is part of the {@link List} interface).  Note that the
570      * {@code remove} method returns the old value that was stored at the
571      * specified position.
572      *
573      * @param      index   the index of the object to remove
574      * @throws ArrayIndexOutOfBoundsException if the index is out of range
575      *         ({@code index < 0 || index >= size()})
576      */

577     public synchronized void removeElementAt(int index) {
578         if (index >= elementCount) {
579             throw new ArrayIndexOutOfBoundsException(index + " >= " +
580                                                      elementCount);
581         }
582         else if (index < 0) {
583             throw new ArrayIndexOutOfBoundsException(index);
584         }
585         int j = elementCount - index - 1;
586         if (j > 0) {
587             System.arraycopy(elementData, index + 1, elementData, index, j);
588         }
589         modCount++;
590         elementCount--;
591         elementData[elementCount] = null/* to let gc do its work */
592     }
593
594     /**
595      * Inserts the specified object as a component in this vector at the
596      * specified {@code index}. Each component in this vector with
597      * an index greater or equal to the specified {@code index} is
598      * shifted upward to have an index one greater than the value it had
599      * previously.
600      *
601      * <p>The index must be a value greater than or equal to {@code 0}
602      * and less than or equal to the current size of the vector. (If the
603      * index is equal to the current size of the vector, the new element
604      * is appended to the Vector.)
605      *
606      * <p>This method is identical in functionality to the
607      * {@link #add(int, Object) add(int, E)}
608      * method (which is part of the {@link List} interface).  Note that the
609      * {@code add} method reverses the order of the parameters, to more closely
610      * match array usage.
611      *
612      * @param      obj     the component to insert
613      * @param      index   where to insert the new component
614      * @throws ArrayIndexOutOfBoundsException if the index is out of range
615      *         ({@code index < 0 || index > size()})
616      */

617     public synchronized void insertElementAt(E obj, int index) {
618         if (index > elementCount) {
619             throw new ArrayIndexOutOfBoundsException(index
620                                                      + " > " + elementCount);
621         }
622         modCount++;
623         final int s = elementCount;
624         Object[] elementData = this.elementData;
625         if (s == elementData.length)
626             elementData = grow();
627         System.arraycopy(elementData, index,
628                          elementData, index + 1,
629                          s - index);
630         elementData[index] = obj;
631         elementCount = s + 1;
632     }
633
634     /**
635      * Adds the specified component to the end of this vector,
636      * increasing its size by one. The capacity of this vector is
637      * increased if its size becomes greater than its capacity.
638      *
639      * <p>This method is identical in functionality to the
640      * {@link #add(Object) add(E)}
641      * method (which is part of the {@link List} interface).
642      *
643      * @param   obj   the component to be added
644      */

645     public synchronized void addElement(E obj) {
646         modCount++;
647         add(obj, elementData, elementCount);
648     }
649
650     /**
651      * Removes the first (lowest-indexed) occurrence of the argument
652      * from this vector. If the object is found in this vector, each
653      * component in the vector with an index greater or equal to the
654      * object's index is shifted downward to have an index one smaller
655      * than the value it had previously.
656      *
657      * <p>This method is identical in functionality to the
658      * {@link #remove(Object)} method (which is part of the
659      * {@link List} interface).
660      *
661      * @param   obj   the component to be removed
662      * @return  {@code trueif the argument was a component of this
663      *          vector; {@code false} otherwise.
664      */

665     public synchronized boolean removeElement(Object obj) {
666         modCount++;
667         int i = indexOf(obj);
668         if (i >= 0) {
669             removeElementAt(i);
670             return true;
671         }
672         return false;
673     }
674
675     /**
676      * Removes all components from this vector and sets its size to zero.
677      *
678      * <p>This method is identical in functionality to the {@link #clear}
679      * method (which is part of the {@link List} interface).
680      */

681     public synchronized void removeAllElements() {
682         final Object[] es = elementData;
683         for (int to = elementCount, i = elementCount = 0; i < to; i++)
684             es[i] = null;
685         modCount++;
686     }
687
688     /**
689      * Returns a clone of this vector. The copy will contain a
690      * reference to a clone of the internal data array, not a reference
691      * to the original internal data array of this {@code Vector} object.
692      *
693      * @return  a clone of this vector
694      */

695     public synchronized Object clone() {
696         try {
697             @SuppressWarnings("unchecked")
698             Vector<E> v = (Vector<E>) super.clone();
699             v.elementData = Arrays.copyOf(elementData, elementCount);
700             v.modCount = 0;
701             return v;
702         } catch (CloneNotSupportedException e) {
703             // this shouldn't happen, since we are Cloneable
704             throw new InternalError(e);
705         }
706     }
707
708     /**
709      * Returns an array containing all of the elements in this Vector
710      * in the correct order.
711      *
712      * @since 1.2
713      */

714     public synchronized Object[] toArray() {
715         return Arrays.copyOf(elementData, elementCount);
716     }
717
718     /**
719      * Returns an array containing all of the elements in this Vector in the
720      * correct order; the runtime type of the returned array is that of the
721      * specified array.  If the Vector fits in the specified array, it is
722      * returned therein.  Otherwise, a new array is allocated with the runtime
723      * type of the specified array and the size of this Vector.
724      *
725      * <p>If the Vector fits in the specified array with room to spare
726      * (i.e., the array has more elements than the Vector),
727      * the element in the array immediately following the end of the
728      * Vector is set to null.  (This is useful in determining the length
729      * of the Vector <em>only</em> if the caller knows that the Vector
730      * does not contain any null elements.)
731      *
732      * @param <T> type of array elements. The same type as {@code <E>} or a
733      * supertype of {@code <E>}.
734      * @param a the array into which the elements of the Vector are to
735      *          be stored, if it is big enough; otherwise, a new array of the
736      *          same runtime type is allocated for this purpose.
737      * @return an array containing the elements of the Vector
738      * @throws ArrayStoreException if the runtime type of a, {@code <T>}, is not
739      * a supertype of the runtime type, {@code <E>}, of every element in this
740      * Vector
741      * @throws NullPointerException if the given array is null
742      * @since 1.2
743      */

744     @SuppressWarnings("unchecked")
745     public synchronized <T> T[] toArray(T[] a) {
746         if (a.length < elementCount)
747             return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
748
749         System.arraycopy(elementData, 0, a, 0, elementCount);
750
751         if (a.length > elementCount)
752             a[elementCount] = null;
753
754         return a;
755     }
756
757     // Positional Access Operations
758
759     @SuppressWarnings("unchecked")
760     E elementData(int index) {
761         return (E) elementData[index];
762     }
763
764     @SuppressWarnings("unchecked")
765     static <E> E elementAt(Object[] es, int index) {
766         return (E) es[index];
767     }
768
769     /**
770      * Returns the element at the specified position in this Vector.
771      *
772      * @param index index of the element to return
773      * @return object at the specified index
774      * @throws ArrayIndexOutOfBoundsException if the index is out of range
775      *            ({@code index < 0 || index >= size()})
776      * @since 1.2
777      */

778     public synchronized E get(int index) {
779         if (index >= elementCount)
780             throw new ArrayIndexOutOfBoundsException(index);
781
782         return elementData(index);
783     }
784
785     /**
786      * Replaces the element at the specified position in this Vector with the
787      * specified element.
788      *
789      * @param index index of the element to replace
790      * @param element element to be stored at the specified position
791      * @return the element previously at the specified position
792      * @throws ArrayIndexOutOfBoundsException if the index is out of range
793      *         ({@code index < 0 || index >= size()})
794      * @since 1.2
795      */

796     public synchronized E set(int index, E element) {
797         if (index >= elementCount)
798             throw new ArrayIndexOutOfBoundsException(index);
799
800         E oldValue = elementData(index);
801         elementData[index] = element;
802         return oldValue;
803     }
804
805     /**
806      * This helper method split out from add(E) to keep method
807      * bytecode size under 35 (the -XX:MaxInlineSize default value),
808      * which helps when add(E) is called in a C1-compiled loop.
809      */

810     private void add(E e, Object[] elementData, int s) {
811         if (s == elementData.length)
812             elementData = grow();
813         elementData[s] = e;
814         elementCount = s + 1;
815     }
816
817     /**
818      * Appends the specified element to the end of this Vector.
819      *
820      * @param e element to be appended to this Vector
821      * @return {@code true} (as specified by {@link Collection#add})
822      * @since 1.2
823      */

824     public synchronized boolean add(E e) {
825         modCount++;
826         add(e, elementData, elementCount);
827         return true;
828     }
829
830     /**
831      * Removes the first occurrence of the specified element in this Vector
832      * If the Vector does not contain the element, it is unchanged.  More
833      * formally, removes the element with the lowest index i such that
834      * {@code Objects.equals(o, get(i))} (if such
835      * an element exists).
836      *
837      * @param o element to be removed from this Vector, if present
838      * @return true if the Vector contained the specified element
839      * @since 1.2
840      */

841     public boolean remove(Object o) {
842         return removeElement(o);
843     }
844
845     /**
846      * Inserts the specified element at the specified position in this Vector.
847      * Shifts the element currently at that position (if any) and any
848      * subsequent elements to the right (adds one to their indices).
849      *
850      * @param index index at which the specified element is to be inserted
851      * @param element element to be inserted
852      * @throws ArrayIndexOutOfBoundsException if the index is out of range
853      *         ({@code index < 0 || index > size()})
854      * @since 1.2
855      */

856     public void add(int index, E element) {
857         insertElementAt(element, index);
858     }
859
860     /**
861      * Removes the element at the specified position in this Vector.
862      * Shifts any subsequent elements to the left (subtracts one from their
863      * indices).  Returns the element that was removed from the Vector.
864      *
865      * @param index the index of the element to be removed
866      * @return element that was removed
867      * @throws ArrayIndexOutOfBoundsException if the index is out of range
868      *         ({@code index < 0 || index >= size()})
869      * @since 1.2
870      */

871     public synchronized E remove(int index) {
872         modCount++;
873         if (index >= elementCount)
874             throw new ArrayIndexOutOfBoundsException(index);
875         E oldValue = elementData(index);
876
877         int numMoved = elementCount - index - 1;
878         if (numMoved > 0)
879             System.arraycopy(elementData, index+1, elementData, index,
880                              numMoved);
881         elementData[--elementCount] = null// Let gc do its work
882
883         return oldValue;
884     }
885
886     /**
887      * Removes all of the elements from this Vector.  The Vector will
888      * be empty after this call returns (unless it throws an exception).
889      *
890      * @since 1.2
891      */

892     public void clear() {
893         removeAllElements();
894     }
895
896     // Bulk Operations
897
898     /**
899      * Returns true if this Vector contains all of the elements in the
900      * specified Collection.
901      *
902      * @param   c a collection whose elements will be tested for containment
903      *          in this Vector
904      * @return true if this Vector contains all of the elements in the
905      *         specified collection
906      * @throws NullPointerException if the specified collection is null
907      */

908     public synchronized boolean containsAll(Collection<?> c) {
909         return super.containsAll(c);
910     }
911
912     /**
913      * Appends all of the elements in the specified Collection to the end of
914      * this Vector, in the order that they are returned by the specified
915      * Collection's Iterator.  The behavior of this operation is undefined if
916      * the specified Collection is modified while the operation is in progress.
917      * (This implies that the behavior of this call is undefined if the
918      * specified Collection is this Vector, and this Vector is nonempty.)
919      *
920      * @param c elements to be inserted into this Vector
921      * @return {@code trueif this Vector changed as a result of the call
922      * @throws NullPointerException if the specified collection is null
923      * @since 1.2
924      */

925     public boolean addAll(Collection<? extends E> c) {
926         Object[] a = c.toArray();
927         modCount++;
928         int numNew = a.length;
929         if (numNew == 0)
930             return false;
931         synchronized (this) {
932             Object[] elementData = this.elementData;
933             final int s = elementCount;
934             if (numNew > elementData.length - s)
935                 elementData = grow(s + numNew);
936             System.arraycopy(a, 0, elementData, s, numNew);
937             elementCount = s + numNew;
938             return true;
939         }
940     }
941
942     /**
943      * Removes from this Vector all of its elements that are contained in the
944      * specified Collection.
945      *
946      * @param c a collection of elements to be removed from the Vector
947      * @return true if this Vector changed as a result of the call
948      * @throws ClassCastException if the types of one or more elements
949      *         in this vector are incompatible with the specified
950      *         collection
951      * (<a href="Collection.html#optional-restrictions">optional</a>)
952      * @throws NullPointerException if this vector contains one or more null
953      *         elements and the specified collection does not support null
954      *         elements
955      * (<a href="Collection.html#optional-restrictions">optional</a>),
956      *         or if the specified collection is null
957      * @since 1.2
958      */

959     public boolean removeAll(Collection<?> c) {
960         Objects.requireNonNull(c);
961         return bulkRemove(e -> c.contains(e));
962     }
963
964     /**
965      * Retains only the elements in this Vector that are contained in the
966      * specified Collection.  In other words, removes from this Vector all
967      * of its elements that are not contained in the specified Collection.
968      *
969      * @param c a collection of elements to be retained in this Vector
970      *          (all other elements are removed)
971      * @return true if this Vector changed as a result of the call
972      * @throws ClassCastException if the types of one or more elements
973      *         in this vector are incompatible with the specified
974      *         collection
975      * (<a href="Collection.html#optional-restrictions">optional</a>)
976      * @throws NullPointerException if this vector contains one or more null
977      *         elements and the specified collection does not support null
978      *         elements
979      *         (<a href="Collection.html#optional-restrictions">optional</a>),
980      *         or if the specified collection is null
981      * @since 1.2
982      */

983     public boolean retainAll(Collection<?> c) {
984         Objects.requireNonNull(c);
985         return bulkRemove(e -> !c.contains(e));
986     }
987
988     /**
989      * @throws NullPointerException {@inheritDoc}
990      */

991     @Override
992     public boolean removeIf(Predicate<? super E> filter) {
993         Objects.requireNonNull(filter);
994         return bulkRemove(filter);
995     }
996
997     // A tiny bit set implementation
998
999     private static long[] nBits(int n) {
1000         return new long[((n - 1) >> 6) + 1];
1001     }
1002     private static void setBit(long[] bits, int i) {
1003         bits[i >> 6] |= 1L << i;
1004     }
1005     private static boolean isClear(long[] bits, int i) {
1006         return (bits[i >> 6] & (1L << i)) == 0;
1007     }
1008
1009     private synchronized boolean bulkRemove(Predicate<? super E> filter) {
1010         int expectedModCount = modCount;
1011         final Object[] es = elementData;
1012         final int end = elementCount;
1013         int i;
1014         // Optimize for initial run of survivors
1015         for (i = 0; i < end && !filter.test(elementAt(es, i)); i++)
1016             ;
1017         // Tolerate predicates that reentrantly access the collection for
1018         // read (but writers still get CME), so traverse once to find
1019         // elements to delete, a second pass to physically expunge.
1020         if (i < end) {
1021             final int beg = i;
1022             final long[] deathRow = nBits(end - beg);
1023             deathRow[0] = 1L;   // set bit 0
1024             for (i = beg + 1; i < end; i++)
1025                 if (filter.test(elementAt(es, i)))
1026                     setBit(deathRow, i - beg);
1027             if (modCount != expectedModCount)
1028                 throw new ConcurrentModificationException();
1029             modCount++;
1030             int w = beg;
1031             for (i = beg; i < end; i++)
1032                 if (isClear(deathRow, i - beg))
1033                     es[w++] = es[i];
1034             for (i = elementCount = w; i < end; i++)
1035                 es[i] = null;
1036             return true;
1037         } else {
1038             if (modCount != expectedModCount)
1039                 throw new ConcurrentModificationException();
1040             return false;
1041         }
1042     }
1043
1044     /**
1045      * Inserts all of the elements in the specified Collection into this
1046      * Vector at the specified position.  Shifts the element currently at
1047      * that position (if any) and any subsequent elements to the right
1048      * (increases their indices).  The new elements will appear in the Vector
1049      * in the order that they are returned by the specified Collection's
1050      * iterator.
1051      *
1052      * @param index index at which to insert the first element from the
1053      *              specified collection
1054      * @param c elements to be inserted into this Vector
1055      * @return {@code trueif this Vector changed as a result of the call
1056      * @throws ArrayIndexOutOfBoundsException if the index is out of range
1057      *         ({@code index < 0 || index > size()})
1058      * @throws NullPointerException if the specified collection is null
1059      * @since 1.2
1060      */

1061     public synchronized boolean addAll(int index, Collection<? extends E> c) {
1062         if (index < 0 || index > elementCount)
1063             throw new ArrayIndexOutOfBoundsException(index);
1064
1065         Object[] a = c.toArray();
1066         modCount++;
1067         int numNew = a.length;
1068         if (numNew == 0)
1069             return false;
1070         Object[] elementData = this.elementData;
1071         final int s = elementCount;
1072         if (numNew > elementData.length - s)
1073             elementData = grow(s + numNew);
1074
1075         int numMoved = s - index;
1076         if (numMoved > 0)
1077             System.arraycopy(elementData, index,
1078                              elementData, index + numNew,
1079                              numMoved);
1080         System.arraycopy(a, 0, elementData, index, numNew);
1081         elementCount = s + numNew;
1082         return true;
1083     }
1084
1085     /**
1086      * Compares the specified Object with this Vector for equality.  Returns
1087      * true if and only if the specified Object is also a List, both Lists
1088      * have the same size, and all corresponding pairs of elements in the two
1089      * Lists are <em>equal</em>.  (Two elements {@code e1} and
1090      * {@code e2} are <em>equal</em> if {@code Objects.equals(e1, e2)}.)
1091      * In other words, two Lists are defined to be
1092      * equal if they contain the same elements in the same order.
1093      *
1094      * @param o the Object to be compared for equality with this Vector
1095      * @return true if the specified Object is equal to this Vector
1096      */

1097     public synchronized boolean equals(Object o) {
1098         return super.equals(o);
1099     }
1100
1101     /**
1102      * Returns the hash code value for this Vector.
1103      */

1104     public synchronized int hashCode() {
1105         return super.hashCode();
1106     }
1107
1108     /**
1109      * Returns a string representation of this Vector, containing
1110      * the String representation of each element.
1111      */

1112     public synchronized String toString() {
1113         return super.toString();
1114     }
1115
1116     /**
1117      * Returns a view of the portion of this List between fromIndex,
1118      * inclusive, and toIndex, exclusive.  (If fromIndex and toIndex are
1119      * equal, the returned List is empty.)  The returned List is backed by this
1120      * List, so changes in the returned List are reflected in this List, and
1121      * vice-versa.  The returned List supports all of the optional List
1122      * operations supported by this List.
1123      *
1124      * <p>This method eliminates the need for explicit range operations (of
1125      * the sort that commonly exist for arrays).  Any operation that expects
1126      * a List can be used as a range operation by operating on a subList view
1127      * instead of a whole List.  For example, the following idiom
1128      * removes a range of elements from a List:
1129      * <pre>
1130      *      list.subList(from, to).clear();
1131      * </pre>
1132      * Similar idioms may be constructed for indexOf and lastIndexOf,
1133      * and all of the algorithms in the Collections class can be applied to
1134      * a subList.
1135      *
1136      * <p>The semantics of the List returned by this method become undefined if
1137      * the backing list (i.e., this List) is <i>structurally modified</i> in
1138      * any way other than via the returned List.  (Structural modifications are
1139      * those that change the size of the List, or otherwise perturb it in such
1140      * a fashion that iterations in progress may yield incorrect results.)
1141      *
1142      * @param fromIndex low endpoint (inclusive) of the subList
1143      * @param toIndex high endpoint (exclusive) of the subList
1144      * @return a view of the specified range within this List
1145      * @throws IndexOutOfBoundsException if an endpoint index value is out of range
1146      *         {@code (fromIndex < 0 || toIndex > size)}
1147      * @throws IllegalArgumentException if the endpoint indices are out of order
1148      *         {@code (fromIndex > toIndex)}
1149      */

1150     public synchronized List<E> subList(int fromIndex, int toIndex) {
1151         return Collections.synchronizedList(super.subList(fromIndex, toIndex),
1152                                             this);
1153     }
1154
1155     /**
1156      * Removes from this list all of the elements whose index is between
1157      * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
1158      * Shifts any succeeding elements to the left (reduces their index).
1159      * This call shortens the list by {@code (toIndex - fromIndex)} elements.
1160      * (If {@code toIndex==fromIndex}, this operation has no effect.)
1161      */

1162     protected synchronized void removeRange(int fromIndex, int toIndex) {
1163         modCount++;
1164         shiftTailOverGap(elementData, fromIndex, toIndex);
1165     }
1166
1167     /** Erases the gap from lo to hi, by sliding down following elements. */
1168     private void shiftTailOverGap(Object[] es, int lo, int hi) {
1169         System.arraycopy(es, hi, es, lo, elementCount - hi);
1170         for (int to = elementCount, i = (elementCount -= hi - lo); i < to; i++)
1171             es[i] = null;
1172     }
1173
1174     /**
1175      * Loads a {@code Vector} instance from a stream
1176      * (that is, deserializes it).
1177      * This method performs checks to ensure the consistency
1178      * of the fields.
1179      *
1180      * @param in the stream
1181      * @throws java.io.IOException if an I/O error occurs
1182      * @throws ClassNotFoundException if the stream contains data
1183      *         of a non-existing class
1184      */

1185     private void readObject(ObjectInputStream in)
1186             throws IOException, ClassNotFoundException {
1187         ObjectInputStream.GetField gfields = in.readFields();
1188         int count = gfields.get("elementCount", 0);
1189         Object[] data = (Object[])gfields.get("elementData"null);
1190         if (count < 0 || data == null || count > data.length) {
1191             throw new StreamCorruptedException("Inconsistent vector internals");
1192         }
1193         elementCount = count;
1194         elementData = data.clone();
1195     }
1196
1197     /**
1198      * Saves the state of the {@code Vector} instance to a stream
1199      * (that is, serializes it).
1200      * This method performs synchronization to ensure the consistency
1201      * of the serialized data.
1202      *
1203      * @param s the stream
1204      * @throws java.io.IOException if an I/O error occurs
1205      */

1206     private void writeObject(java.io.ObjectOutputStream s)
1207             throws java.io.IOException {
1208         final java.io.ObjectOutputStream.PutField fields = s.putFields();
1209         final Object[] data;
1210         synchronized (this) {
1211             fields.put("capacityIncrement", capacityIncrement);
1212             fields.put("elementCount", elementCount);
1213             data = elementData.clone();
1214         }
1215         fields.put("elementData", data);
1216         s.writeFields();
1217     }
1218
1219     /**
1220      * Returns a list iterator over the elements in this list (in proper
1221      * sequence), starting at the specified position in the list.
1222      * The specified index indicates the first element that would be
1223      * returned by an initial call to {@link ListIterator#next next}.
1224      * An initial call to {@link ListIterator#previous previous} would
1225      * return the element with the specified index minus one.
1226      *
1227      * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
1228      *
1229      * @throws IndexOutOfBoundsException {@inheritDoc}
1230      */

1231     public synchronized ListIterator<E> listIterator(int index) {
1232         if (index < 0 || index > elementCount)
1233             throw new IndexOutOfBoundsException("Index: "+index);
1234         return new ListItr(index);
1235     }
1236
1237     /**
1238      * Returns a list iterator over the elements in this list (in proper
1239      * sequence).
1240      *
1241      * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
1242      *
1243      * @see #listIterator(int)
1244      */

1245     public synchronized ListIterator<E> listIterator() {
1246         return new ListItr(0);
1247     }
1248
1249     /**
1250      * Returns an iterator over the elements in this list in proper sequence.
1251      *
1252      * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
1253      *
1254      * @return an iterator over the elements in this list in proper sequence
1255      */

1256     public synchronized Iterator<E> iterator() {
1257         return new Itr();
1258     }
1259
1260     /**
1261      * An optimized version of AbstractList.Itr
1262      */

1263     private class Itr implements Iterator<E> {
1264         int cursor;       // index of next element to return
1265         int lastRet = -1; // index of last element returned; -1 if no such
1266         int expectedModCount = modCount;
1267
1268         public boolean hasNext() {
1269             // Racy but within spec, since modifications are checked
1270             // within or after synchronization in next/previous
1271             return cursor != elementCount;
1272         }
1273
1274         public E next() {
1275             synchronized (Vector.this) {
1276                 checkForComodification();
1277                 int i = cursor;
1278                 if (i >= elementCount)
1279                     throw new NoSuchElementException();
1280                 cursor = i + 1;
1281                 return elementData(lastRet = i);
1282             }
1283         }
1284
1285         public void remove() {
1286             if (lastRet == -1)
1287                 throw new IllegalStateException();
1288             synchronized (Vector.this) {
1289                 checkForComodification();
1290                 Vector.this.remove(lastRet);
1291                 expectedModCount = modCount;
1292             }
1293             cursor = lastRet;
1294             lastRet = -1;
1295         }
1296
1297         @Override
1298         public void forEachRemaining(Consumer<? super E> action) {
1299             Objects.requireNonNull(action);
1300             synchronized (Vector.this) {
1301                 final int size = elementCount;
1302                 int i = cursor;
1303                 if (i >= size) {
1304                     return;
1305                 }
1306                 final Object[] es = elementData;
1307                 if (i >= es.length)
1308                     throw new ConcurrentModificationException();
1309                 while (i < size && modCount == expectedModCount)
1310                     action.accept(elementAt(es, i++));
1311                 // update once at end of iteration to reduce heap write traffic
1312                 cursor = i;
1313                 lastRet = i - 1;
1314                 checkForComodification();
1315             }
1316         }
1317
1318         final void checkForComodification() {
1319             if (modCount != expectedModCount)
1320                 throw new ConcurrentModificationException();
1321         }
1322     }
1323
1324     /**
1325      * An optimized version of AbstractList.ListItr
1326      */

1327     final class ListItr extends Itr implements ListIterator<E> {
1328         ListItr(int index) {
1329             super();
1330             cursor = index;
1331         }
1332
1333         public boolean hasPrevious() {
1334             return cursor != 0;
1335         }
1336
1337         public int nextIndex() {
1338             return cursor;
1339         }
1340
1341         public int previousIndex() {
1342             return cursor - 1;
1343         }
1344
1345         public E previous() {
1346             synchronized (Vector.this) {
1347                 checkForComodification();
1348                 int i = cursor - 1;
1349                 if (i < 0)
1350                     throw new NoSuchElementException();
1351                 cursor = i;
1352                 return elementData(lastRet = i);
1353             }
1354         }
1355
1356         public void set(E e) {
1357             if (lastRet == -1)
1358                 throw new IllegalStateException();
1359             synchronized (Vector.this) {
1360                 checkForComodification();
1361                 Vector.this.set(lastRet, e);
1362             }
1363         }
1364
1365         public void add(E e) {
1366             int i = cursor;
1367             synchronized (Vector.this) {
1368                 checkForComodification();
1369                 Vector.this.add(i, e);
1370                 expectedModCount = modCount;
1371             }
1372             cursor = i + 1;
1373             lastRet = -1;
1374         }
1375     }
1376
1377     /**
1378      * @throws NullPointerException {@inheritDoc}
1379      */

1380     @Override
1381     public synchronized void forEach(Consumer<? super E> action) {
1382         Objects.requireNonNull(action);
1383         final int expectedModCount = modCount;
1384         final Object[] es = elementData;
1385         final int size = elementCount;
1386         for (int i = 0; modCount == expectedModCount && i < size; i++)
1387             action.accept(elementAt(es, i));
1388         if (modCount != expectedModCount)
1389             throw new ConcurrentModificationException();
1390     }
1391
1392     /**
1393      * @throws NullPointerException {@inheritDoc}
1394      */

1395     @Override
1396     public synchronized void replaceAll(UnaryOperator<E> operator) {
1397         Objects.requireNonNull(operator);
1398         final int expectedModCount = modCount;
1399         final Object[] es = elementData;
1400         final int size = elementCount;
1401         for (int i = 0; modCount == expectedModCount && i < size; i++)
1402             es[i] = operator.apply(elementAt(es, i));
1403         if (modCount != expectedModCount)
1404             throw new ConcurrentModificationException();
1405         modCount++;
1406     }
1407
1408     @SuppressWarnings("unchecked")
1409     @Override
1410     public synchronized void sort(Comparator<? super E> c) {
1411         final int expectedModCount = modCount;
1412         Arrays.sort((E[]) elementData, 0, elementCount, c);
1413         if (modCount != expectedModCount)
1414             throw new ConcurrentModificationException();
1415         modCount++;
1416     }
1417
1418     /**
1419      * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
1420      * and <em>fail-fast</em> {@link Spliterator} over the elements in this
1421      * list.
1422      *
1423      * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
1424      * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.
1425      * Overriding implementations should document the reporting of additional
1426      * characteristic values.
1427      *
1428      * @return a {@code Spliterator} over the elements in this list
1429      * @since 1.8
1430      */

1431     @Override
1432     public Spliterator<E> spliterator() {
1433         return new VectorSpliterator(null, 0, -1, 0);
1434     }
1435
1436     /** Similar to ArrayList Spliterator */
1437     final class VectorSpliterator implements Spliterator<E> {
1438         private Object[] array;
1439         private int index; // current index, modified on advance/split
1440         private int fence; // -1 until used; then one past last index
1441         private int expectedModCount; // initialized when fence set
1442
1443         /** Creates new spliterator covering the given range. */
1444         VectorSpliterator(Object[] array, int origin, int fence,
1445                           int expectedModCount) {
1446             this.array = array;
1447             this.index = origin;
1448             this.fence = fence;
1449             this.expectedModCount = expectedModCount;
1450         }
1451
1452         private int getFence() { // initialize on first use
1453             int hi;
1454             if ((hi = fence) < 0) {
1455                 synchronized (Vector.this) {
1456                     array = elementData;
1457                     expectedModCount = modCount;
1458                     hi = fence = elementCount;
1459                 }
1460             }
1461             return hi;
1462         }
1463
1464         public Spliterator<E> trySplit() {
1465             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
1466             return (lo >= mid) ? null :
1467                 new VectorSpliterator(array, lo, index = mid, expectedModCount);
1468         }
1469
1470         @SuppressWarnings("unchecked")
1471         public boolean tryAdvance(Consumer<? super E> action) {
1472             Objects.requireNonNull(action);
1473             int i;
1474             if (getFence() > (i = index)) {
1475                 index = i + 1;
1476                 action.accept((E)array[i]);
1477                 if (modCount != expectedModCount)
1478                     throw new ConcurrentModificationException();
1479                 return true;
1480             }
1481             return false;
1482         }
1483
1484         @SuppressWarnings("unchecked")
1485         public void forEachRemaining(Consumer<? super E> action) {
1486             Objects.requireNonNull(action);
1487             final int hi = getFence();
1488             final Object[] a = array;
1489             int i;
1490             for (i = index, index = hi; i < hi; i++)
1491                 action.accept((E) a[i]);
1492             if (modCount != expectedModCount)
1493                 throw new ConcurrentModificationException();
1494         }
1495
1496         public long estimateSize() {
1497             return getFence() - index;
1498         }
1499
1500         public int characteristics() {
1501             return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
1502         }
1503     }
1504
1505     void checkInvariants() {
1506         // assert elementCount >= 0;
1507         // assert elementCount == elementData.length || elementData[elementCount] == null;
1508     }
1509 }
1510