ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/Vector.java
Revision: 1.8
Committed: Tue Feb 7 20:54:24 2006 UTC (18 years, 3 months ago) by jsr166
Branch: MAIN
Changes since 1.7: +0 -1 lines
Log Message:
6378729: Remove workaround for 6280605

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