ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/Vector.java
Revision: 1.57
Committed: Thu Oct 10 16:53:08 2019 UTC (4 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.56: +1 -0 lines
Log Message:
8231202: Suppress warnings on non-serializable non-transient instance fields in serializable classes

File Contents

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