• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 package java.util;
19 
20 import java.io.IOException;
21 import java.io.ObjectOutputStream;
22 import java.io.Serializable;
23 import java.lang.reflect.Array;
24 
25 /**
26  * Vector is a variable size contiguous indexable array of objects. The size of
27  * the vector is the number of objects it contains. The capacity of the vector
28  * is the number of objects it can hold.
29  * <p>
30  * Objects may be inserted at any position up to the size of the vector, thus
31  * increasing the size of the vector. Objects at any position in the vector may
32  * be removed, thus shrinking the size of the Vector. Objects at any position in
33  * the Vector may be replaced, which does not affect the vector's size.
34  * <p>
35  * The capacity of a vector may be specified when the vector is created. If the
36  * capacity of the vector is exceeded, the capacity is increased (doubled by
37  * default).
38  *
39  * @see java.lang.StringBuffer
40  */
41 public class Vector<E> extends AbstractList<E> implements List<E>,
42         RandomAccess, Cloneable, Serializable {
43 
44     private static final long serialVersionUID = -2767605614048989439L;
45 
46     /**
47      * The number of elements or the size of the vector.
48      */
49     protected int elementCount;
50 
51     /**
52      * The elements of the vector.
53      */
54     protected Object[] elementData;
55 
56     /**
57      * How many elements should be added to the vector when it is detected that
58      * it needs to grow to accommodate extra entries. If this value is zero or
59      * negative the size will be doubled if an increase is needed.
60      */
61     protected int capacityIncrement;
62 
63     private static final int DEFAULT_SIZE = 10;
64 
65     /**
66      * Constructs a new vector using the default capacity.
67      */
Vector()68     public Vector() {
69         this(DEFAULT_SIZE, 0);
70     }
71 
72     /**
73      * Constructs a new vector using the specified capacity.
74      *
75      * @param capacity
76      *            the initial capacity of the new vector.
77      * @throws IllegalArgumentException
78      *             if {@code capacity} is negative.
79      */
Vector(int capacity)80     public Vector(int capacity) {
81         this(capacity, 0);
82     }
83 
84     /**
85      * Constructs a new vector using the specified capacity and capacity
86      * increment.
87      *
88      * @param capacity
89      *            the initial capacity of the new vector.
90      * @param capacityIncrement
91      *            the amount to increase the capacity when this vector is full.
92      * @throws IllegalArgumentException
93      *             if {@code capacity} is negative.
94      */
Vector(int capacity, int capacityIncrement)95     public Vector(int capacity, int capacityIncrement) {
96         if (capacity < 0) {
97             throw new IllegalArgumentException();
98         }
99         elementData = newElementArray(capacity);
100         elementCount = 0;
101         this.capacityIncrement = capacityIncrement;
102     }
103 
104     /**
105      * Constructs a new instance of {@code Vector} containing the elements in
106      * {@code collection}. The order of the elements in the new {@code Vector}
107      * is dependent on the iteration order of the seed collection.
108      *
109      * @param collection
110      *            the collection of elements to add.
111      */
Vector(Collection<? extends E> collection)112     public Vector(Collection<? extends E> collection) {
113         this(collection.size(), 0);
114         Iterator<? extends E> it = collection.iterator();
115         while (it.hasNext()) {
116             elementData[elementCount++] = it.next();
117         }
118     }
119 
120     @SuppressWarnings("unchecked")
newElementArray(int size)121     private E[] newElementArray(int size) {
122         return (E[]) new Object[size];
123     }
124 
125     /**
126      * Adds the specified object into this vector at the specified location. The
127      * object is inserted before any element with the same or a higher index
128      * increasing their index by 1. If the location is equal to the size of this
129      * vector, the object is added at the end.
130      *
131      * @param location
132      *            the index at which to insert the element.
133      * @param object
134      *            the object to insert in this vector.
135      * @throws ArrayIndexOutOfBoundsException
136      *                if {@code location < 0 || location > size()}.
137      * @see #addElement
138      * @see #size
139      */
140     @Override
add(int location, E object)141     public void add(int location, E object) {
142         insertElementAt(object, location);
143     }
144 
145     /**
146      * Adds the specified object at the end of this vector.
147      *
148      * @param object
149      *            the object to add to the vector.
150      * @return {@code true}
151      */
152     @Override
add(E object)153     public synchronized boolean add(E object) {
154         if (elementCount == elementData.length) {
155             growByOne();
156         }
157         elementData[elementCount++] = object;
158         modCount++;
159         return true;
160     }
161 
162     /**
163      * Inserts the objects in the specified collection at the specified location
164      * in this vector. The objects are inserted in the order in which they are
165      * returned from the Collection iterator. The elements with an index equal
166      * or higher than {@code location} have their index increased by the size of
167      * the added collection.
168      *
169      * @param location
170      *            the location to insert the objects.
171      * @param collection
172      *            the collection of objects.
173      * @return {@code true} if this vector is modified, {@code false} otherwise.
174      * @throws ArrayIndexOutOfBoundsException
175      *                if {@code location < 0} or {@code location > size()}.
176      */
177     @Override
addAll(int location, Collection<? extends E> collection)178     public synchronized boolean addAll(int location,
179             Collection<? extends E> collection) {
180         if (0 <= location && location <= elementCount) {
181             int size = collection.size();
182             if (size == 0) {
183                 return false;
184             }
185             int required = size - (elementData.length - elementCount);
186             if (required > 0) {
187                 growBy(required);
188             }
189             int count = elementCount - location;
190             if (count > 0) {
191                 System.arraycopy(elementData, location, elementData, location
192                         + size, count);
193             }
194             Iterator<? extends E> it = collection.iterator();
195             while (it.hasNext()) {
196                 elementData[location++] = it.next();
197             }
198             elementCount += size;
199             modCount++;
200             return true;
201         }
202         throw new ArrayIndexOutOfBoundsException(location);
203     }
204 
205     /**
206      * Adds the objects in the specified collection to the end of this vector.
207      *
208      * @param collection
209      *            the collection of objects.
210      * @return {@code true} if this vector is modified, {@code false} otherwise.
211      */
212     @Override
addAll(Collection<? extends E> collection)213     public synchronized boolean addAll(Collection<? extends E> collection) {
214         return addAll(elementCount, collection);
215     }
216 
217     /**
218      * Adds the specified object at the end of this vector.
219      *
220      * @param object
221      *            the object to add to the vector.
222      */
addElement(E object)223     public synchronized void addElement(E object) {
224         if (elementCount == elementData.length) {
225             growByOne();
226         }
227         elementData[elementCount++] = object;
228         modCount++;
229     }
230 
231     /**
232      * Returns the number of elements this vector can hold without growing.
233      *
234      * @return the capacity of this vector.
235      * @see #ensureCapacity
236      * @see #size
237      */
capacity()238     public synchronized int capacity() {
239         return elementData.length;
240     }
241 
242     /**
243      * Removes all elements from this vector, leaving it empty.
244      *
245      * @see #isEmpty
246      * @see #size
247      */
248     @Override
clear()249     public void clear() {
250         removeAllElements();
251     }
252 
253     /**
254      * Returns a new vector with the same elements, size, capacity and capacity
255      * increment as this vector.
256      *
257      * @return a shallow copy of this vector.
258      * @see java.lang.Cloneable
259      */
260     @Override
261     @SuppressWarnings("unchecked")
clone()262     public synchronized Object clone() {
263         try {
264             Vector<E> vector = (Vector<E>) super.clone();
265             vector.elementData = elementData.clone();
266             return vector;
267         } catch (CloneNotSupportedException e) {
268             return null;
269         }
270     }
271 
272     /**
273      * Searches this vector for the specified object.
274      *
275      * @param object
276      *            the object to look for in this vector.
277      * @return {@code true} if object is an element of this vector,
278      *         {@code false} otherwise.
279      * @see #indexOf(Object)
280      * @see #indexOf(Object, int)
281      * @see java.lang.Object#equals
282      */
283     @Override
contains(Object object)284     public boolean contains(Object object) {
285         return indexOf(object, 0) != -1;
286     }
287 
288     /**
289      * Searches this vector for all objects in the specified collection.
290      *
291      * @param collection
292      *            the collection of objects.
293      * @return {@code true} if all objects in the specified collection are
294      *         elements of this vector, {@code false} otherwise.
295      */
296     @Override
containsAll(Collection<?> collection)297     public synchronized boolean containsAll(Collection<?> collection) {
298         return super.containsAll(collection);
299     }
300 
301     /**
302      * Attempts to copy elements contained by this {@code Vector} into the
303      * corresponding elements of the supplied {@code Object} array.
304      *
305      * @param elements
306      *            the {@code Object} array into which the elements of this
307      *            vector are copied.
308      * @throws IndexOutOfBoundsException
309      *             if {@code elements} is not big enough.
310      * @see #clone
311      */
copyInto(Object[] elements)312     public synchronized void copyInto(Object[] elements) {
313         System.arraycopy(elementData, 0, elements, 0, elementCount);
314     }
315 
316     /**
317      * Returns the element at the specified location in this vector.
318      *
319      * @param location
320      *            the index of the element to return in this vector.
321      * @return the element at the specified location.
322      * @throws ArrayIndexOutOfBoundsException
323      *                if {@code location < 0 || location >= size()}.
324      * @see #size
325      */
326     @SuppressWarnings("unchecked")
elementAt(int location)327     public synchronized E elementAt(int location) {
328         if (location < elementCount) {
329             return (E) elementData[location];
330         }
331         throw new ArrayIndexOutOfBoundsException(location);
332     }
333 
334     /**
335      * Returns an enumeration on the elements of this vector. The results of the
336      * enumeration may be affected if the contents of this vector is modified.
337      *
338      * @return an enumeration of the elements of this vector.
339      * @see #elementAt
340      * @see Enumeration
341      */
elements()342     public Enumeration<E> elements() {
343         return new Enumeration<E>() {
344             int pos = 0;
345 
346             public boolean hasMoreElements() {
347                 return pos < elementCount;
348             }
349 
350             @SuppressWarnings("unchecked")
351             public E nextElement() {
352                 synchronized (Vector.this) {
353                     if (pos < elementCount) {
354                         return (E) elementData[pos++];
355                     }
356                 }
357                 throw new NoSuchElementException();
358             }
359         };
360     }
361 
362     /**
363      * Ensures that this vector can hold the specified number of elements
364      * without growing.
365      *
366      * @param minimumCapacity
367      *            the minimum number of elements that this vector will hold
368      *            before growing.
369      * @see #capacity
370      */
ensureCapacity(int minimumCapacity)371     public synchronized void ensureCapacity(int minimumCapacity) {
372         if (elementData.length < minimumCapacity) {
373             int next = (capacityIncrement <= 0 ? elementData.length
374                     : capacityIncrement)
375                     + elementData.length;
376             grow(minimumCapacity > next ? minimumCapacity : next);
377         }
378     }
379 
380     /**
381      * Compares the specified object to this vector and returns if they are
382      * equal. The object must be a List which contains the same objects in the
383      * same order.
384      *
385      * @param object
386      *            the object to compare with this object
387      * @return {@code true} if the specified object is equal to this vector,
388      *         {@code false} otherwise.
389      * @see #hashCode
390      */
391     @Override
equals(Object object)392     public synchronized boolean equals(Object object) {
393         if (this == object) {
394             return true;
395         }
396         if (object instanceof List) {
397             List<?> list = (List<?>) object;
398             if (list.size() != elementCount) {
399                 return false;
400             }
401 
402             int index = 0;
403             Iterator<?> it = list.iterator();
404             while (it.hasNext()) {
405                 Object e1 = elementData[index++], e2 = it.next();
406                 if (!(e1 == null ? e2 == null : e1.equals(e2))) {
407                     return false;
408                 }
409             }
410             return true;
411         }
412         return false;
413     }
414 
415     /**
416      * Returns the first element in this vector.
417      *
418      * @return the element at the first position.
419      * @throws NoSuchElementException
420      *                if this vector is empty.
421      * @see #elementAt
422      * @see #lastElement
423      * @see #size
424      */
425     @SuppressWarnings("unchecked")
firstElement()426     public synchronized E firstElement() {
427         if (elementCount > 0) {
428             return (E) elementData[0];
429         }
430         throw new NoSuchElementException();
431     }
432 
433     /**
434      * Returns the element at the specified location in this vector.
435      *
436      * @param location
437      *            the index of the element to return in this vector.
438      * @return the element at the specified location.
439      * @throws ArrayIndexOutOfBoundsException
440      *                if {@code location < 0 || location >= size()}.
441      * @see #size
442      */
443     @Override
get(int location)444     public E get(int location) {
445         return elementAt(location);
446     }
447 
grow(int newCapacity)448     private void grow(int newCapacity) {
449         E[] newData = newElementArray(newCapacity);
450         // Assumes elementCount is <= newCapacity
451         assert elementCount <= newCapacity;
452         System.arraycopy(elementData, 0, newData, 0, elementCount);
453         elementData = newData;
454     }
455 
456     /**
457      * JIT optimization
458      */
growByOne()459     private void growByOne() {
460         int adding = 0;
461         if (capacityIncrement <= 0) {
462             if ((adding = elementData.length) == 0) {
463                 adding = 1;
464             }
465         } else {
466             adding = capacityIncrement;
467         }
468 
469         E[] newData = newElementArray(elementData.length + adding);
470         System.arraycopy(elementData, 0, newData, 0, elementCount);
471         elementData = newData;
472     }
473 
growBy(int required)474     private void growBy(int required) {
475         int adding = 0;
476         if (capacityIncrement <= 0) {
477             if ((adding = elementData.length) == 0) {
478                 adding = required;
479             }
480             while (adding < required) {
481                 adding += adding;
482             }
483         } else {
484             adding = (required / capacityIncrement) * capacityIncrement;
485             if (adding < required) {
486                 adding += capacityIncrement;
487             }
488         }
489         E[] newData = newElementArray(elementData.length + adding);
490         System.arraycopy(elementData, 0, newData, 0, elementCount);
491         elementData = newData;
492     }
493 
494     /**
495      * Returns an integer hash code for the receiver. Objects which are equal
496      * return the same value for this method.
497      *
498      * @return the receiver's hash.
499      * @see #equals
500      */
501     @Override
hashCode()502     public synchronized int hashCode() {
503         int result = 1;
504         for (int i = 0; i < elementCount; i++) {
505             result = (31 * result)
506                     + (elementData[i] == null ? 0 : elementData[i].hashCode());
507         }
508         return result;
509     }
510 
511     /**
512      * Searches in this vector for the index of the specified object. The search
513      * for the object starts at the beginning and moves towards the end of this
514      * vector.
515      *
516      * @param object
517      *            the object to find in this vector.
518      * @return the index in this vector of the specified element, -1 if the
519      *         element isn't found.
520      * @see #contains
521      * @see #lastIndexOf(Object)
522      * @see #lastIndexOf(Object, int)
523      */
524     @Override
indexOf(Object object)525     public int indexOf(Object object) {
526         return indexOf(object, 0);
527     }
528 
529     /**
530      * Searches in this vector for the index of the specified object. The search
531      * for the object starts at the specified location and moves towards the end
532      * of this vector.
533      *
534      * @param object
535      *            the object to find in this vector.
536      * @param location
537      *            the index at which to start searching.
538      * @return the index in this vector of the specified element, -1 if the
539      *         element isn't found.
540      * @throws ArrayIndexOutOfBoundsException
541      *                if {@code location < 0}.
542      * @see #contains
543      * @see #lastIndexOf(Object)
544      * @see #lastIndexOf(Object, int)
545      */
indexOf(Object object, int location)546     public synchronized int indexOf(Object object, int location) {
547         if (object != null) {
548             for (int i = location; i < elementCount; i++) {
549                 if (object.equals(elementData[i])) {
550                     return i;
551                 }
552             }
553         } else {
554             for (int i = location; i < elementCount; i++) {
555                 if (elementData[i] == null) {
556                     return i;
557                 }
558             }
559         }
560         return -1;
561     }
562 
563     /**
564      * Inserts the specified object into this vector at the specified location.
565      * This object is inserted before any previous element at the specified
566      * location. All elements with an index equal or greater than
567      * {@code location} have their index increased by 1. If the location is
568      * equal to the size of this vector, the object is added at the end.
569      *
570      * @param object
571      *            the object to insert in this vector.
572      * @param location
573      *            the index at which to insert the element.
574      * @throws ArrayIndexOutOfBoundsException
575      *                if {@code location < 0 || location > size()}.
576      * @see #addElement
577      * @see #size
578      */
insertElementAt(E object, int location)579     public synchronized void insertElementAt(E object, int location) {
580         if (0 <= location && location <= elementCount) {
581             if (elementCount == elementData.length) {
582                 growByOne();
583             }
584             int count = elementCount - location;
585             if (count > 0) {
586                 System.arraycopy(elementData, location, elementData,
587                         location + 1, count);
588             }
589             elementData[location] = object;
590             elementCount++;
591             modCount++;
592         } else {
593             throw new ArrayIndexOutOfBoundsException(location);
594         }
595     }
596 
597     /**
598      * Returns if this vector has no elements, a size of zero.
599      *
600      * @return {@code true} if this vector has no elements, {@code false}
601      *         otherwise.
602      * @see #size
603      */
604     @Override
isEmpty()605     public synchronized boolean isEmpty() {
606         return elementCount == 0;
607     }
608 
609     /**
610      * Returns the last element in this vector.
611      *
612      * @return the element at the last position.
613      * @throws NoSuchElementException
614      *                if this vector is empty.
615      * @see #elementAt
616      * @see #firstElement
617      * @see #size
618      */
619     @SuppressWarnings("unchecked")
lastElement()620     public synchronized E lastElement() {
621         try {
622             return (E) elementData[elementCount - 1];
623         } catch (IndexOutOfBoundsException e) {
624             throw new NoSuchElementException();
625         }
626     }
627 
628     /**
629      * Searches in this vector for the index of the specified object. The search
630      * for the object starts at the end and moves towards the start of this
631      * vector.
632      *
633      * @param object
634      *            the object to find in this vector.
635      * @return the index in this vector of the specified element, -1 if the
636      *         element isn't found.
637      * @see #contains
638      * @see #indexOf(Object)
639      * @see #indexOf(Object, int)
640      */
641     @Override
lastIndexOf(Object object)642     public synchronized int lastIndexOf(Object object) {
643         return lastIndexOf(object, elementCount - 1);
644     }
645 
646     /**
647      * Searches in this vector for the index of the specified object. The search
648      * for the object starts at the specified location and moves towards the
649      * start of this vector.
650      *
651      * @param object
652      *            the object to find in this vector.
653      * @param location
654      *            the index at which to start searching.
655      * @return the index in this vector of the specified element, -1 if the
656      *         element isn't found.
657      * @throws ArrayIndexOutOfBoundsException
658      *                if {@code location >= size()}.
659      * @see #contains
660      * @see #indexOf(Object)
661      * @see #indexOf(Object, int)
662      */
lastIndexOf(Object object, int location)663     public synchronized int lastIndexOf(Object object, int location) {
664         if (location < elementCount) {
665             if (object != null) {
666                 for (int i = location; i >= 0; i--) {
667                     if (object.equals(elementData[i])) {
668                         return i;
669                     }
670                 }
671             } else {
672                 for (int i = location; i >= 0; i--) {
673                     if (elementData[i] == null) {
674                         return i;
675                     }
676                 }
677             }
678             return -1;
679         }
680         throw new ArrayIndexOutOfBoundsException(location);
681     }
682 
683     /**
684      * Removes the object at the specified location from this vector. All
685      * elements with an index bigger than {@code location} have their index
686      * decreased by 1.
687      *
688      * @param location
689      *            the index of the object to remove.
690      * @return the removed object.
691      * @throws IndexOutOfBoundsException
692      *                if {@code location < 0 || location >= size()}.
693      */
694     @SuppressWarnings("unchecked")
695     @Override
remove(int location)696     public synchronized E remove(int location) {
697         if (location < elementCount) {
698             E result = (E) elementData[location];
699             elementCount--;
700             int size = elementCount - location;
701             if (size > 0) {
702                 System.arraycopy(elementData, location + 1, elementData,
703                         location, size);
704             }
705             elementData[elementCount] = null;
706             modCount++;
707             return result;
708         }
709         throw new ArrayIndexOutOfBoundsException(location);
710     }
711 
712     /**
713      * Removes the first occurrence, starting at the beginning and moving
714      * towards the end, of the specified object from this vector. All elements
715      * with an index bigger than the element that gets removed have their index
716      * decreased by 1.
717      *
718      * @param object
719      *            the object to remove from this vector.
720      * @return {@code true} if the specified object was found, {@code false}
721      *         otherwise.
722      * @see #removeAllElements
723      * @see #removeElementAt
724      * @see #size
725      */
726     @Override
remove(Object object)727     public boolean remove(Object object) {
728         return removeElement(object);
729     }
730 
731     /**
732      * Removes all occurrences in this vector of each object in the specified
733      * Collection.
734      *
735      * @param collection
736      *            the collection of objects to remove.
737      * @return {@code true} if this vector is modified, {@code false} otherwise.
738      * @see #remove(Object)
739      * @see #contains(Object)
740      */
741     @Override
removeAll(Collection<?> collection)742     public synchronized boolean removeAll(Collection<?> collection) {
743         return super.removeAll(collection);
744     }
745 
746     /**
747      * Removes all elements from this vector, leaving the size zero and the
748      * capacity unchanged.
749      *
750      * @see #isEmpty
751      * @see #size
752      */
removeAllElements()753     public synchronized void removeAllElements() {
754         for (int i = 0; i < elementCount; i++) {
755             elementData[i] = null;
756         }
757         modCount++;
758         elementCount = 0;
759     }
760 
761     /**
762      * Removes the first occurrence, starting at the beginning and moving
763      * towards the end, of the specified object from this vector. All elements
764      * with an index bigger than the element that gets removed have their index
765      * decreased by 1.
766      *
767      * @param object
768      *            the object to remove from this vector.
769      * @return {@code true} if the specified object was found, {@code false}
770      *         otherwise.
771      * @see #removeAllElements
772      * @see #removeElementAt
773      * @see #size
774      */
removeElement(Object object)775     public synchronized boolean removeElement(Object object) {
776         int index;
777         if ((index = indexOf(object, 0)) == -1) {
778             return false;
779         }
780         removeElementAt(index);
781         return true;
782     }
783 
784     /**
785      * Removes the element found at index position {@code location} from
786      * this {@code Vector}. All elements with an index bigger than
787      * {@code location} have their index decreased by 1.
788      *
789      * @param location
790      *            the index of the element to remove.
791      * @throws ArrayIndexOutOfBoundsException
792      *                if {@code location < 0 || location >= size()}.
793      * @see #removeElement
794      * @see #removeAllElements
795      * @see #size
796      */
removeElementAt(int location)797     public synchronized void removeElementAt(int location) {
798         if (0 <= location && location < elementCount) {
799             elementCount--;
800             int size = elementCount - location;
801             if (size > 0) {
802                 System.arraycopy(elementData, location + 1, elementData,
803                         location, size);
804             }
805             elementData[elementCount] = null;
806             modCount++;
807         } else {
808             throw new ArrayIndexOutOfBoundsException(location);
809         }
810     }
811 
812     /**
813      * Removes the objects in the specified range from the start to the, but not
814      * including, end index. All elements with an index bigger than or equal to
815      * {@code end} have their index decreased by {@code end - start}.
816      *
817      * @param start
818      *            the index at which to start removing.
819      * @param end
820      *            the index one past the end of the range to remove.
821      * @throws IndexOutOfBoundsException
822      *                if {@code start < 0, start > end} or
823      *                {@code end > size()}.
824      */
825     @Override
removeRange(int start, int end)826     protected void removeRange(int start, int end) {
827         if (start >= 0 && start <= end && end <= elementCount) {
828             if (start == end) {
829                 return;
830             }
831             if (end != elementCount) {
832                 System.arraycopy(elementData, end, elementData, start,
833                         elementCount - end);
834                 int newCount = elementCount - (end - start);
835                 Arrays.fill(elementData, newCount, elementCount, null);
836                 elementCount = newCount;
837             } else {
838                 Arrays.fill(elementData, start, elementCount, null);
839                 elementCount = start;
840             }
841             modCount++;
842         } else {
843             throw new IndexOutOfBoundsException();
844         }
845     }
846 
847     /**
848      * Removes all objects from this vector that are not contained in the
849      * specified collection.
850      *
851      * @param collection
852      *            the collection of objects to retain.
853      * @return {@code true} if this vector is modified, {@code false} otherwise.
854      * @see #remove(Object)
855      */
856     @Override
retainAll(Collection<?> collection)857     public synchronized boolean retainAll(Collection<?> collection) {
858         return super.retainAll(collection);
859     }
860 
861     /**
862      * Replaces the element at the specified location in this vector with the
863      * specified object.
864      *
865      * @param location
866      *            the index at which to put the specified object.
867      * @param object
868      *            the object to add to this vector.
869      * @return the previous element at the location.
870      * @throws ArrayIndexOutOfBoundsException
871      *                if {@code location < 0 || location >= size()}.
872      * @see #size
873      */
874     @SuppressWarnings("unchecked")
875     @Override
set(int location, E object)876     public synchronized E set(int location, E object) {
877         if (location < elementCount) {
878             E result = (E) elementData[location];
879             elementData[location] = object;
880             return result;
881         }
882         throw new ArrayIndexOutOfBoundsException(location);
883     }
884 
885     /**
886      * Replaces the element at the specified location in this vector with the
887      * specified object.
888      *
889      * @param object
890      *            the object to add to this vector.
891      * @param location
892      *            the index at which to put the specified object.
893      * @throws ArrayIndexOutOfBoundsException
894      *                if {@code location < 0 || location >= size()}.
895      * @see #size
896      */
setElementAt(E object, int location)897     public synchronized void setElementAt(E object, int location) {
898         if (location < elementCount) {
899             elementData[location] = object;
900         } else {
901             throw new ArrayIndexOutOfBoundsException(location);
902         }
903     }
904 
905     /**
906      * Sets the size of this vector to the specified size. If there are more
907      * than length elements in this vector, the elements at end are lost. If
908      * there are less than length elements in the vector, the additional
909      * elements contain null.
910      *
911      * @param length
912      *            the new size of this vector.
913      * @see #size
914      */
setSize(int length)915     public synchronized void setSize(int length) {
916         if (length == elementCount) {
917             return;
918         }
919         ensureCapacity(length);
920         if (elementCount > length) {
921             Arrays.fill(elementData, length, elementCount, null);
922         }
923         elementCount = length;
924         modCount++;
925     }
926 
927     /**
928      * Returns the number of elements in this vector.
929      *
930      * @return the number of elements in this vector.
931      * @see #elementCount
932      * @see #lastElement
933      */
934     @Override
size()935     public synchronized int size() {
936         return elementCount;
937     }
938 
939     /**
940      * Returns a List of the specified portion of this vector from the start
941      * index to one less than the end index. The returned List is backed by this
942      * vector so changes to one are reflected by the other.
943      *
944      * @param start
945      *            the index at which to start the sublist.
946      * @param end
947      *            the index one past the end of the sublist.
948      * @return a List of a portion of this vector.
949      * @throws IndexOutOfBoundsException
950      *                if {@code start < 0} or {@code end > size()}.
951      * @throws IllegalArgumentException
952      *                if {@code start > end}.
953      */
954     @Override
subList(int start, int end)955     public synchronized List<E> subList(int start, int end) {
956         return new Collections.SynchronizedRandomAccessList<E>(super.subList(
957                 start, end), this);
958     }
959 
960     /**
961      * Returns a new array containing all elements contained in this vector.
962      *
963      * @return an array of the elements from this vector.
964      */
965     @Override
toArray()966     public synchronized Object[] toArray() {
967         Object[] result = new Object[elementCount];
968         System.arraycopy(elementData, 0, result, 0, elementCount);
969         return result;
970     }
971 
972     /**
973      * Returns an array containing all elements contained in this vector. If the
974      * specified array is large enough to hold the elements, the specified array
975      * is used, otherwise an array of the same type is created. If the specified
976      * array is used and is larger than this vector, the array element following
977      * the collection elements is set to null.
978      *
979      * @param contents
980      *            the array to fill.
981      * @return an array of the elements from this vector.
982      * @throws ArrayStoreException
983      *                if the type of an element in this vector cannot be
984      *                stored in the type of the specified array.
985      */
986     @Override
987     @SuppressWarnings("unchecked")
toArray(T[] contents)988     public synchronized <T> T[] toArray(T[] contents) {
989         if (elementCount > contents.length) {
990             Class<?> ct = contents.getClass().getComponentType();
991             contents = (T[]) Array.newInstance(ct, elementCount);
992         }
993         System.arraycopy(elementData, 0, contents, 0, elementCount);
994         if (elementCount < contents.length) {
995             contents[elementCount] = null;
996         }
997         return contents;
998     }
999 
1000     /**
1001      * Returns the string representation of this vector.
1002      *
1003      * @return the string representation of this vector.
1004      * @see #elements
1005      */
1006     @Override
toString()1007     public synchronized String toString() {
1008         if (elementCount == 0) {
1009             return "[]"; //$NON-NLS-1$
1010         }
1011         int length = elementCount - 1;
1012         StringBuilder buffer = new StringBuilder(elementCount * 16);
1013         buffer.append('[');
1014         for (int i = 0; i < length; i++) {
1015             if (elementData[i] == this) {
1016                 buffer.append("(this Collection)"); //$NON-NLS-1$
1017             } else {
1018                 buffer.append(elementData[i]);
1019             }
1020             buffer.append(", "); //$NON-NLS-1$
1021         }
1022         if (elementData[length] == this) {
1023             buffer.append("(this Collection)"); //$NON-NLS-1$
1024         } else {
1025             buffer.append(elementData[length]);
1026         }
1027         buffer.append(']');
1028         return buffer.toString();
1029     }
1030 
1031     /**
1032      * Sets the capacity of this vector to be the same as the size.
1033      *
1034      * @see #capacity
1035      * @see #ensureCapacity
1036      * @see #size
1037      */
trimToSize()1038     public synchronized void trimToSize() {
1039         if (elementData.length != elementCount) {
1040             grow(elementCount);
1041         }
1042     }
1043 
writeObject(ObjectOutputStream stream)1044     private synchronized void writeObject(ObjectOutputStream stream)
1045             throws IOException {
1046         stream.defaultWriteObject();
1047     }
1048 }
1049