ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/Vector.java
Revision: 1.2
Committed: Sat Nov 26 03:12:10 2005 UTC (18 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.1: +6 -6 lines
Log Message:
whitespace

File Contents

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