ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/Vector.java
Revision: 1.7
Committed: Mon Dec 5 02:56:59 2005 UTC (18 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.6: +1 -1 lines
Log Message:
copyright update for 2006

File Contents

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