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