ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/Vector.java
Revision: 1.15
Committed: Sun Jun 25 19:58:14 2006 UTC (17 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.14: +23 -27 lines
Log Message:
doc sync with mustang

File Contents

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