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