ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/Vector.java
Revision: 1.20
Committed: Sun Jan 7 07:38:27 2007 UTC (17 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.19: +1 -1 lines
Log Message:
copyright year update

File Contents

# User Rev Content
1 dl 1.1 /*
2 jsr166 1.12 * %W% %E%
3 dl 1.1 *
4 jsr166 1.20 * Copyright 2007 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 jsr166 1.16 * @param newSize the new size of this vector
237     * @throws ArrayIndexOutOfBoundsException if the new size is negative
238 dl 1.1 */
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 jsr166 1.16 * position is discarded.
465 dl 1.1 *
466 jsr166 1.16 * <p>The index must be a value greater than or equal to {@code 0}
467     * and less than the current size of the vector.
468 dl 1.1 *
469 jsr166 1.17 * <p>This method is identical in functionality to the
470     * {@link #set(int, Object) set(int, E)}
471     * method (which is part of the {@link List} interface). Note that the
472     * {@code set} method reverses the order of the parameters, to more closely
473     * match array usage. Note also that the {@code set} method returns the
474     * old value that was stored at the specified position.
475 dl 1.1 *
476     * @param obj what the component is to be set to
477     * @param index the specified index
478 jsr166 1.17 * @throws ArrayIndexOutOfBoundsException if the index is out of range
479     * ({@code index < 0 || index >= size()})
480 dl 1.1 */
481     public synchronized void setElementAt(E obj, int index) {
482     if (index >= elementCount) {
483     throw new ArrayIndexOutOfBoundsException(index + " >= " +
484     elementCount);
485     }
486     elementData[index] = obj;
487     }
488    
489     /**
490     * Deletes the component at the specified index. Each component in
491     * this vector with an index greater or equal to the specified
492 jsr166 1.14 * {@code index} is shifted downward to have an index one
493 dl 1.1 * smaller than the value it had previously. The size of this vector
494 jsr166 1.15 * is decreased by {@code 1}.
495 dl 1.1 *
496 jsr166 1.15 * <p>The index must be a value greater than or equal to {@code 0}
497     * and less than the current size of the vector.
498 dl 1.1 *
499 jsr166 1.17 * <p>This method is identical in functionality to the {@link #remove(int)}
500     * method (which is part of the {@link List} interface). Note that the
501     * {@code remove} method returns the old value that was stored at the
502     * specified position.
503 dl 1.1 *
504     * @param index the index of the object to remove
505 jsr166 1.17 * @throws ArrayIndexOutOfBoundsException if the index is out of range
506     * ({@code index < 0 || index >= size()})
507 dl 1.1 */
508     public synchronized void removeElementAt(int index) {
509     modCount++;
510     if (index >= elementCount) {
511     throw new ArrayIndexOutOfBoundsException(index + " >= " +
512     elementCount);
513     }
514     else if (index < 0) {
515     throw new ArrayIndexOutOfBoundsException(index);
516     }
517     int j = elementCount - index - 1;
518     if (j > 0) {
519     System.arraycopy(elementData, index + 1, elementData, index, j);
520     }
521     elementCount--;
522     elementData[elementCount] = null; /* to let gc do its work */
523     }
524    
525     /**
526     * Inserts the specified object as a component in this vector at the
527 jsr166 1.14 * specified {@code index}. Each component in this vector with
528     * an index greater or equal to the specified {@code index} is
529 dl 1.1 * shifted upward to have an index one greater than the value it had
530 jsr166 1.15 * previously.
531 dl 1.1 *
532 jsr166 1.15 * <p>The index must be a value greater than or equal to {@code 0}
533 dl 1.1 * and less than or equal to the current size of the vector. (If the
534     * index is equal to the current size of the vector, the new element
535 jsr166 1.15 * is appended to the Vector.)
536 dl 1.1 *
537 jsr166 1.17 * <p>This method is identical in functionality to the
538     * {@link #add(int, Object) add(int, E)}
539     * method (which is part of the {@link List} interface). Note that the
540     * {@code add} method reverses the order of the parameters, to more closely
541     * match array usage.
542 dl 1.1 *
543     * @param obj the component to insert
544     * @param index where to insert the new component
545 jsr166 1.17 * @throws ArrayIndexOutOfBoundsException if the index is out of range
546     * ({@code index < 0 || index > size()})
547 dl 1.1 */
548     public synchronized void insertElementAt(E obj, int index) {
549     modCount++;
550     if (index > elementCount) {
551     throw new ArrayIndexOutOfBoundsException(index
552     + " > " + elementCount);
553     }
554     ensureCapacityHelper(elementCount + 1);
555     System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
556     elementData[index] = obj;
557     elementCount++;
558     }
559    
560     /**
561     * Adds the specified component to the end of this vector,
562     * increasing its size by one. The capacity of this vector is
563 jsr166 1.16 * increased if its size becomes greater than its capacity.
564 dl 1.1 *
565 jsr166 1.17 * <p>This method is identical in functionality to the
566 jsr166 1.18 * {@link #add(Object) add(E)}
567     * method (which is part of the {@link List} interface).
568 dl 1.1 *
569     * @param obj the component to be added
570     */
571     public synchronized void addElement(E obj) {
572     modCount++;
573     ensureCapacityHelper(elementCount + 1);
574     elementData[elementCount++] = obj;
575     }
576    
577     /**
578     * Removes the first (lowest-indexed) occurrence of the argument
579     * from this vector. If the object is found in this vector, each
580     * component in the vector with an index greater or equal to the
581     * object's index is shifted downward to have an index one smaller
582 jsr166 1.16 * than the value it had previously.
583 dl 1.1 *
584 jsr166 1.18 * <p>This method is identical in functionality to the
585     * {@link #remove(Object)} method (which is part of the
586     * {@link List} interface).
587 dl 1.1 *
588     * @param obj the component to be removed
589 jsr166 1.14 * @return {@code true} if the argument was a component of this
590     * vector; {@code false} otherwise.
591 dl 1.1 */
592     public synchronized boolean removeElement(Object obj) {
593     modCount++;
594     int i = indexOf(obj);
595     if (i >= 0) {
596     removeElementAt(i);
597     return true;
598     }
599     return false;
600     }
601    
602     /**
603 jsr166 1.17 * Removes all components from this vector and sets its size to zero.
604 dl 1.1 *
605 jsr166 1.17 * <p>This method is identical in functionality to the {@link #clear}
606     * method (which is part of the {@link List} interface).
607 dl 1.1 */
608     public synchronized void removeAllElements() {
609     modCount++;
610     // Let gc do its work
611     for (int i = 0; i < elementCount; i++)
612     elementData[i] = null;
613    
614     elementCount = 0;
615     }
616    
617     /**
618     * Returns a clone of this vector. The copy will contain a
619     * reference to a clone of the internal data array, not a reference
620 jsr166 1.14 * to the original internal data array of this {@code Vector} object.
621 dl 1.1 *
622     * @return a clone of this vector
623     */
624     public synchronized Object clone() {
625     try {
626     Vector<E> v = (Vector<E>) super.clone();
627     v.elementData = Arrays.copyOf(elementData, elementCount);
628     v.modCount = 0;
629     return v;
630     } catch (CloneNotSupportedException e) {
631     // this shouldn't happen, since we are Cloneable
632     throw new InternalError();
633     }
634     }
635    
636     /**
637     * Returns an array containing all of the elements in this Vector
638     * in the correct order.
639     *
640     * @since 1.2
641     */
642     public synchronized Object[] toArray() {
643     return Arrays.copyOf(elementData, elementCount);
644     }
645    
646     /**
647     * Returns an array containing all of the elements in this Vector in the
648     * correct order; the runtime type of the returned array is that of the
649     * specified array. If the Vector fits in the specified array, it is
650     * returned therein. Otherwise, a new array is allocated with the runtime
651 jsr166 1.16 * type of the specified array and the size of this Vector.
652 dl 1.1 *
653 jsr166 1.16 * <p>If the Vector fits in the specified array with room to spare
654 dl 1.1 * (i.e., the array has more elements than the Vector),
655     * the element in the array immediately following the end of the
656     * Vector is set to null. (This is useful in determining the length
657     * of the Vector <em>only</em> if the caller knows that the Vector
658     * does not contain any null elements.)
659     *
660     * @param a the array into which the elements of the Vector are to
661     * be stored, if it is big enough; otherwise, a new array of the
662     * same runtime type is allocated for this purpose.
663     * @return an array containing the elements of the Vector
664 jsr166 1.17 * @throws ArrayStoreException if the runtime type of a is not a supertype
665 dl 1.1 * of the runtime type of every element in this Vector
666     * @throws NullPointerException if the given array is null
667     * @since 1.2
668     */
669     public synchronized <T> T[] toArray(T[] a) {
670     if (a.length < elementCount)
671     return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
672    
673     System.arraycopy(elementData, 0, a, 0, elementCount);
674    
675     if (a.length > elementCount)
676     a[elementCount] = null;
677    
678     return a;
679     }
680    
681     // Positional Access Operations
682    
683     /**
684     * Returns the element at the specified position in this Vector.
685     *
686     * @param index index of the element to return
687     * @return object at the specified index
688 jsr166 1.17 * @throws ArrayIndexOutOfBoundsException if the index is out of range
689     * ({@code index < 0 || index >= size()})
690 dl 1.1 * @since 1.2
691     */
692     public synchronized E get(int index) {
693     if (index >= elementCount)
694     throw new ArrayIndexOutOfBoundsException(index);
695    
696     return (E)elementData[index];
697     }
698    
699     /**
700     * Replaces the element at the specified position in this Vector with the
701     * specified element.
702     *
703     * @param index index of the element to replace
704     * @param element element to be stored at the specified position
705     * @return the element previously at the specified position
706 jsr166 1.17 * @throws ArrayIndexOutOfBoundsException if the index is out of range
707     * ({@code index < 0 || index >= size()})
708 dl 1.1 * @since 1.2
709     */
710     public synchronized E set(int index, E element) {
711     if (index >= elementCount)
712     throw new ArrayIndexOutOfBoundsException(index);
713    
714     Object oldValue = elementData[index];
715     elementData[index] = element;
716     return (E)oldValue;
717     }
718    
719     /**
720     * Appends the specified element to the end of this Vector.
721     *
722     * @param e element to be appended to this Vector
723 jsr166 1.14 * @return {@code true} (as specified by {@link Collection#add})
724 dl 1.1 * @since 1.2
725     */
726     public synchronized boolean add(E e) {
727     modCount++;
728     ensureCapacityHelper(elementCount + 1);
729     elementData[elementCount++] = e;
730     return true;
731     }
732    
733     /**
734     * Removes the first occurrence of the specified element in this Vector
735     * If the Vector does not contain the element, it is unchanged. More
736     * formally, removes the element with the lowest index i such that
737 jsr166 1.14 * {@code (o==null ? get(i)==null : o.equals(get(i)))} (if such
738 dl 1.1 * an element exists).
739     *
740     * @param o element to be removed from this Vector, if present
741     * @return true if the Vector contained the specified element
742     * @since 1.2
743     */
744     public boolean remove(Object o) {
745     return removeElement(o);
746     }
747    
748     /**
749     * Inserts the specified element at the specified position in this Vector.
750     * Shifts the element currently at that position (if any) and any
751     * subsequent elements to the right (adds one to their indices).
752     *
753     * @param index index at which the specified element is to be inserted
754     * @param element element to be inserted
755 jsr166 1.17 * @throws ArrayIndexOutOfBoundsException if the index is out of range
756     * ({@code index < 0 || index > size()})
757 dl 1.1 * @since 1.2
758     */
759     public void add(int index, E element) {
760     insertElementAt(element, index);
761     }
762    
763     /**
764     * Removes the element at the specified position in this Vector.
765     * Shifts any subsequent elements to the left (subtracts one from their
766     * indices). Returns the element that was removed from the Vector.
767     *
768 jsr166 1.18 * @throws ArrayIndexOutOfBoundsException if the index is out of range
769     * ({@code index < 0 || index >= size()})
770 dl 1.1 * @param index the index of the element to be removed
771     * @return element that was removed
772     * @since 1.2
773     */
774     public synchronized E remove(int index) {
775     modCount++;
776     if (index >= elementCount)
777     throw new ArrayIndexOutOfBoundsException(index);
778     Object oldValue = elementData[index];
779    
780     int numMoved = elementCount - index - 1;
781     if (numMoved > 0)
782     System.arraycopy(elementData, index+1, elementData, index,
783     numMoved);
784     elementData[--elementCount] = null; // Let gc do its work
785    
786     return (E)oldValue;
787     }
788    
789     /**
790     * Removes all of the elements from this Vector. The Vector will
791     * be empty after this call returns (unless it throws an exception).
792     *
793     * @since 1.2
794     */
795     public void clear() {
796     removeAllElements();
797     }
798    
799     // Bulk Operations
800    
801     /**
802     * Returns true if this Vector contains all of the elements in the
803     * specified Collection.
804     *
805     * @param c a collection whose elements will be tested for containment
806     * in this Vector
807     * @return true if this Vector contains all of the elements in the
808     * specified collection
809     * @throws NullPointerException if the specified collection is null
810     */
811     public synchronized boolean containsAll(Collection<?> c) {
812     return super.containsAll(c);
813     }
814    
815     /**
816     * Appends all of the elements in the specified Collection to the end of
817     * this Vector, in the order that they are returned by the specified
818     * Collection's Iterator. The behavior of this operation is undefined if
819     * the specified Collection is modified while the operation is in progress.
820     * (This implies that the behavior of this call is undefined if the
821     * specified Collection is this Vector, and this Vector is nonempty.)
822     *
823     * @param c elements to be inserted into this Vector
824 jsr166 1.14 * @return {@code true} if this Vector changed as a result of the call
825 dl 1.1 * @throws NullPointerException if the specified collection is null
826     * @since 1.2
827     */
828     public synchronized boolean addAll(Collection<? extends E> c) {
829     modCount++;
830     Object[] a = c.toArray();
831     int numNew = a.length;
832     ensureCapacityHelper(elementCount + numNew);
833     System.arraycopy(a, 0, elementData, elementCount, numNew);
834     elementCount += numNew;
835     return numNew != 0;
836     }
837    
838     /**
839     * Removes from this Vector all of its elements that are contained in the
840     * specified Collection.
841     *
842     * @param c a collection of elements to be removed from the Vector
843     * @return true if this Vector changed as a result of the call
844     * @throws ClassCastException if the types of one or more elements
845     * in this vector are incompatible with the specified
846     * collection (optional)
847     * @throws NullPointerException if this vector contains one or more null
848     * elements and the specified collection does not support null
849     * elements (optional), or if the specified collection is null
850     * @since 1.2
851     */
852     public synchronized boolean removeAll(Collection<?> c) {
853     return super.removeAll(c);
854     }
855    
856     /**
857     * Retains only the elements in this Vector that are contained in the
858     * specified Collection. In other words, removes from this Vector all
859     * of its elements that are not contained in the specified Collection.
860     *
861     * @param c a collection of elements to be retained in this Vector
862     * (all other elements are removed)
863     * @return true if this Vector changed as a result of the call
864     * @throws ClassCastException if the types of one or more elements
865     * in this vector are incompatible with the specified
866     * collection (optional)
867     * @throws NullPointerException if this vector contains one or more null
868     * elements and the specified collection does not support null
869     * elements (optional), or if the specified collection is null
870     * @since 1.2
871     */
872     public synchronized boolean retainAll(Collection<?> c) {
873     return super.retainAll(c);
874     }
875    
876     /**
877     * Inserts all of the elements in the specified Collection into this
878     * Vector at the specified position. Shifts the element currently at
879     * that position (if any) and any subsequent elements to the right
880     * (increases their indices). The new elements will appear in the Vector
881     * in the order that they are returned by the specified Collection's
882     * iterator.
883     *
884     * @param index index at which to insert the first element from the
885     * specified collection
886     * @param c elements to be inserted into this Vector
887 jsr166 1.14 * @return {@code true} if this Vector changed as a result of the call
888 jsr166 1.18 * @throws ArrayIndexOutOfBoundsException if the index is out of range
889     * ({@code index < 0 || index > size()})
890 dl 1.1 * @throws NullPointerException if the specified collection is null
891     * @since 1.2
892     */
893     public synchronized boolean addAll(int index, Collection<? extends E> c) {
894     modCount++;
895     if (index < 0 || index > elementCount)
896     throw new ArrayIndexOutOfBoundsException(index);
897    
898     Object[] a = c.toArray();
899     int numNew = a.length;
900     ensureCapacityHelper(elementCount + numNew);
901    
902     int numMoved = elementCount - index;
903     if (numMoved > 0)
904     System.arraycopy(elementData, index, elementData, index + numNew,
905     numMoved);
906    
907     System.arraycopy(a, 0, elementData, index, numNew);
908     elementCount += numNew;
909     return numNew != 0;
910     }
911    
912     /**
913     * Compares the specified Object with this Vector for equality. Returns
914     * true if and only if the specified Object is also a List, both Lists
915     * have the same size, and all corresponding pairs of elements in the two
916 jsr166 1.14 * Lists are <em>equal</em>. (Two elements {@code e1} and
917     * {@code e2} are <em>equal</em> if {@code (e1==null ? e2==null :
918     * e1.equals(e2))}.) In other words, two Lists are defined to be
919 dl 1.1 * equal if they contain the same elements in the same order.
920     *
921     * @param o the Object to be compared for equality with this Vector
922     * @return true if the specified Object is equal to this Vector
923     */
924     public synchronized boolean equals(Object o) {
925     return super.equals(o);
926     }
927    
928     /**
929     * Returns the hash code value for this Vector.
930     */
931     public synchronized int hashCode() {
932     return super.hashCode();
933     }
934    
935     /**
936     * Returns a string representation of this Vector, containing
937     * the String representation of each element.
938     */
939     public synchronized String toString() {
940     return super.toString();
941     }
942    
943     /**
944     * Removes from this List all of the elements whose index is between
945     * fromIndex, inclusive and toIndex, exclusive. Shifts any succeeding
946     * elements to the left (reduces their index).
947 dl 1.10 * This call shortens the Vector by (toIndex - fromIndex) elements. (If
948 dl 1.1 * toIndex==fromIndex, this operation has no effect.)
949     *
950     * @param fromIndex index of first element to be removed
951     * @param toIndex index after last element to be removed
952     */
953     protected synchronized void removeRange(int fromIndex, int toIndex) {
954     modCount++;
955     int numMoved = elementCount - toIndex;
956     System.arraycopy(elementData, toIndex, elementData, fromIndex,
957     numMoved);
958    
959     // Let gc do its work
960     int newElementCount = elementCount - (toIndex-fromIndex);
961     while (elementCount != newElementCount)
962     elementData[--elementCount] = null;
963     }
964    
965     /**
966 jsr166 1.14 * Save the state of the {@code Vector} instance to a stream (that
967 dl 1.1 * is, serialize it). This method is present merely for synchronization.
968     * It just calls the default writeObject method.
969     */
970     private synchronized void writeObject(java.io.ObjectOutputStream s)
971     throws java.io.IOException
972     {
973     s.defaultWriteObject();
974     }
975    
976     /**
977     * Returns a list-iterator of the elements in this list (in proper
978     * sequence), starting at the specified position in the list.
979 dl 1.10 * Obeys the general contract of {@link List#listIterator(int)}.
980 dl 1.1 *
981 dl 1.10 * <p>The list-iterator is <i>fail-fast</i>: if the list is structurally
982 dl 1.1 * modified at any time after the Iterator is created, in any way except
983 dl 1.10 * through the list-iterator's own {@code remove} or {@code add}
984 dl 1.1 * methods, the list-iterator will throw a
985 dl 1.10 * {@code ConcurrentModificationException}. Thus, in the face of
986 dl 1.1 * concurrent modification, the iterator fails quickly and cleanly, rather
987     * than risking arbitrary, non-deterministic behavior at an undetermined
988     * time in the future.
989     *
990     * @param index index of the first element to be returned from the
991 dl 1.10 * list-iterator (by a call to {@link ListIterator#next})
992     * @return a list-iterator of the elements in this list (in proper
993 dl 1.1 * sequence), starting at the specified position in the list
994     * @throws IndexOutOfBoundsException {@inheritDoc}
995     */
996     public synchronized ListIterator<E> listIterator(int index) {
997     if (index < 0 || index > elementCount)
998     throw new IndexOutOfBoundsException("Index: "+index);
999 dl 1.10 return new VectorIterator(index, elementCount);
1000 dl 1.1 }
1001 jsr166 1.2
1002 dl 1.1 /**
1003 dl 1.3 * {@inheritDoc}
1004     */
1005     public synchronized ListIterator<E> listIterator() {
1006 dl 1.10 return new VectorIterator(0, elementCount);
1007 dl 1.3 }
1008    
1009     /**
1010 dl 1.1 * Returns an iterator over the elements in this list in proper sequence.
1011     *
1012     * @return an iterator over the elements in this list in proper sequence
1013     */
1014     public synchronized Iterator<E> iterator() {
1015 dl 1.10 return new VectorIterator(0, elementCount);
1016 dl 1.1 }
1017    
1018     /**
1019 dl 1.10 * Helper method to access array elements under synchronization by
1020     * iterators. The caller performs index check with respect to
1021     * expected bounds, so errors accessing the element are reported
1022     * as ConcurrentModificationExceptions.
1023     */
1024     final synchronized Object iteratorGet(int index, int expectedModCount) {
1025     if (modCount == expectedModCount) {
1026     try {
1027     return elementData[index];
1028     } catch(IndexOutOfBoundsException fallThrough) {
1029     }
1030     }
1031     throw new ConcurrentModificationException();
1032     }
1033    
1034     /**
1035     * Streamlined specialization of AbstractList version of iterator.
1036 jsr166 1.19 * Locally performs bounds checks, but relies on outer Vector
1037 dl 1.10 * to access elements under synchronization.
1038 dl 1.1 */
1039 dl 1.3 private final class VectorIterator implements ListIterator<E> {
1040 dl 1.10 int cursor; // Index of next element to return;
1041     int fence; // Upper bound on cursor (cache of size())
1042     int lastRet; // Index of last element, or -1 if no such
1043     int expectedModCount; // To check for CME
1044    
1045     VectorIterator(int index, int fence) {
1046     this.cursor = index;
1047     this.fence = fence;
1048     this.lastRet = -1;
1049     this.expectedModCount = Vector.this.modCount;
1050 dl 1.1 }
1051    
1052     public boolean hasNext() {
1053 dl 1.10 return cursor < fence;
1054 dl 1.1 }
1055    
1056     public boolean hasPrevious() {
1057 dl 1.10 return cursor > 0;
1058 dl 1.1 }
1059    
1060     public int nextIndex() {
1061     return cursor;
1062     }
1063    
1064     public int previousIndex() {
1065     return cursor - 1;
1066     }
1067    
1068     public E next() {
1069 dl 1.10 int i = cursor;
1070     if (i >= fence)
1071 dl 1.3 throw new NoSuchElementException();
1072 dl 1.10 Object next = Vector.this.iteratorGet(i, expectedModCount);
1073     lastRet = i;
1074     cursor = i + 1;
1075     return (E)next;
1076 dl 1.1 }
1077 jsr166 1.4
1078 dl 1.10 public E previous() {
1079     int i = cursor - 1;
1080     if (i < 0)
1081 dl 1.3 throw new NoSuchElementException();
1082 dl 1.10 Object prev = Vector.this.iteratorGet(i, expectedModCount);
1083     lastRet = i;
1084     cursor = i;
1085     return (E)prev;
1086 dl 1.1 }
1087    
1088 dl 1.10 public void set(E e) {
1089     if (lastRet < 0)
1090 dl 1.1 throw new IllegalStateException();
1091 dl 1.10 if (Vector.this.modCount != expectedModCount)
1092     throw new ConcurrentModificationException();
1093     try {
1094     Vector.this.set(lastRet, e);
1095     expectedModCount = Vector.this.modCount;
1096 jsr166 1.4 } catch (IndexOutOfBoundsException ex) {
1097 dl 1.3 throw new ConcurrentModificationException();
1098     }
1099 dl 1.1 }
1100    
1101 dl 1.10 public void remove() {
1102     int i = lastRet;
1103     if (i < 0)
1104 dl 1.1 throw new IllegalStateException();
1105 dl 1.10 if (Vector.this.modCount != expectedModCount)
1106 dl 1.3 throw new ConcurrentModificationException();
1107 dl 1.10 try {
1108     Vector.this.remove(i);
1109     if (i < cursor)
1110     cursor--;
1111     lastRet = -1;
1112     fence = Vector.this.size();
1113     expectedModCount = Vector.this.modCount;
1114 dl 1.3 } catch (IndexOutOfBoundsException ex) {
1115     throw new ConcurrentModificationException();
1116     }
1117 dl 1.1 }
1118    
1119     public void add(E e) {
1120 dl 1.10 if (Vector.this.modCount != expectedModCount)
1121 dl 1.3 throw new ConcurrentModificationException();
1122     try {
1123     int i = cursor;
1124 dl 1.10 Vector.this.add(i, e);
1125 dl 1.3 cursor = i + 1;
1126 dl 1.10 lastRet = -1;
1127     fence = Vector.this.size();
1128     expectedModCount = Vector.this.modCount;
1129 dl 1.3 } catch (IndexOutOfBoundsException ex) {
1130     throw new ConcurrentModificationException();
1131     }
1132 dl 1.1 }
1133     }
1134 dl 1.10
1135     /**
1136     * Returns a view of the portion of this List between fromIndex,
1137     * inclusive, and toIndex, exclusive. (If fromIndex and toIndex are
1138     * equal, the returned List is empty.) The returned List is backed by this
1139     * List, so changes in the returned List are reflected in this List, and
1140     * vice-versa. The returned List supports all of the optional List
1141 jsr166 1.16 * operations supported by this List.
1142 dl 1.10 *
1143 jsr166 1.16 * <p>This method eliminates the need for explicit range operations (of
1144 dl 1.10 * the sort that commonly exist for arrays). Any operation that expects
1145     * a List can be used as a range operation by operating on a subList view
1146     * instead of a whole List. For example, the following idiom
1147     * removes a range of elements from a List:
1148     * <pre>
1149     * list.subList(from, to).clear();
1150     * </pre>
1151     * Similar idioms may be constructed for indexOf and lastIndexOf,
1152     * and all of the algorithms in the Collections class can be applied to
1153 jsr166 1.16 * a subList.
1154 dl 1.10 *
1155 jsr166 1.16 * <p>The semantics of the List returned by this method become undefined if
1156 dl 1.10 * the backing list (i.e., this List) is <i>structurally modified</i> in
1157     * any way other than via the returned List. (Structural modifications are
1158     * those that change the size of the List, or otherwise perturb it in such
1159     * a fashion that iterations in progress may yield incorrect results.)
1160     *
1161     * @param fromIndex low endpoint (inclusive) of the subList
1162     * @param toIndex high endpoint (exclusive) of the subList
1163     * @return a view of the specified range within this List
1164 jsr166 1.18 * @throws IndexOutOfBoundsException if an endpoint index value is out of range
1165     * {@code (fromIndex < 0 || toIndex > size)}
1166     * @throws IllegalArgumentException if the endpoint indices are out of order
1167     * {@code (fromIndex > toIndex)}
1168 dl 1.10 */
1169     public synchronized List<E> subList(int fromIndex, int toIndex) {
1170     return new VectorSubList(this, this, fromIndex, fromIndex, toIndex);
1171     }
1172    
1173     /**
1174     * This class specializes the AbstractList version of SubList to
1175     * avoid the double-indirection penalty that would arise using a
1176     * synchronized wrapper, as well as to avoid some unnecessary
1177     * checks in sublist iterators.
1178     */
1179     private static final class VectorSubList<E> extends AbstractList<E> implements RandomAccess {
1180     final Vector<E> base; // base list
1181     final AbstractList<E> parent; // Creating list
1182     final int baseOffset; // index wrt Vector
1183     final int parentOffset; // index wrt parent
1184     int length; // length of sublist
1185    
1186 jsr166 1.11 VectorSubList(Vector<E> base, AbstractList<E> parent, int baseOffset,
1187 dl 1.10 int fromIndex, int toIndex) {
1188     if (fromIndex < 0)
1189     throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
1190     if (toIndex > parent.size())
1191     throw new IndexOutOfBoundsException("toIndex = " + toIndex);
1192     if (fromIndex > toIndex)
1193     throw new IllegalArgumentException("fromIndex(" + fromIndex +
1194     ") > toIndex(" + toIndex + ")");
1195    
1196     this.base = base;
1197     this.parent = parent;
1198     this.baseOffset = baseOffset;
1199     this.parentOffset = fromIndex;
1200     this.length = toIndex - fromIndex;
1201     modCount = base.modCount;
1202     }
1203    
1204     /**
1205     * Returns an IndexOutOfBoundsException with nicer message
1206     */
1207     private IndexOutOfBoundsException indexError(int index) {
1208 jsr166 1.11 return new IndexOutOfBoundsException("Index: " + index +
1209 dl 1.10 ", Size: " + length);
1210     }
1211    
1212     public E set(int index, E element) {
1213     synchronized(base) {
1214     if (index < 0 || index >= length)
1215     throw indexError(index);
1216     if (base.modCount != modCount)
1217     throw new ConcurrentModificationException();
1218     return base.set(index + baseOffset, element);
1219     }
1220     }
1221    
1222     public E get(int index) {
1223     synchronized(base) {
1224     if (index < 0 || index >= length)
1225     throw indexError(index);
1226     if (base.modCount != modCount)
1227     throw new ConcurrentModificationException();
1228     return base.get(index + baseOffset);
1229     }
1230     }
1231    
1232     public int size() {
1233     synchronized(base) {
1234     if (base.modCount != modCount)
1235     throw new ConcurrentModificationException();
1236     return length;
1237     }
1238     }
1239    
1240     public void add(int index, E element) {
1241     synchronized(base) {
1242     if (index < 0 || index > length)
1243     throw indexError(index);
1244     if (base.modCount != modCount)
1245     throw new ConcurrentModificationException();
1246     parent.add(index + parentOffset, element);
1247     length++;
1248     modCount = base.modCount;
1249     }
1250     }
1251    
1252     public E remove(int index) {
1253     synchronized(base) {
1254     if (index < 0 || index >= length)
1255     throw indexError(index);
1256     if (base.modCount != modCount)
1257     throw new ConcurrentModificationException();
1258     E result = parent.remove(index + parentOffset);
1259     length--;
1260     modCount = base.modCount;
1261     return result;
1262     }
1263     }
1264    
1265     protected void removeRange(int fromIndex, int toIndex) {
1266     synchronized(base) {
1267     if (base.modCount != modCount)
1268     throw new ConcurrentModificationException();
1269 jsr166 1.11 parent.removeRange(fromIndex + parentOffset,
1270 dl 1.10 toIndex + parentOffset);
1271     length -= (toIndex-fromIndex);
1272     modCount = base.modCount;
1273     }
1274     }
1275    
1276     public boolean addAll(Collection<? extends E> c) {
1277     return addAll(length, c);
1278     }
1279    
1280     public boolean addAll(int index, Collection<? extends E> c) {
1281     synchronized(base) {
1282     if (index < 0 || index > length)
1283     throw indexError(index);
1284     int cSize = c.size();
1285     if (cSize==0)
1286     return false;
1287 jsr166 1.11
1288 dl 1.10 if (base.modCount != modCount)
1289     throw new ConcurrentModificationException();
1290     parent.addAll(parentOffset + index, c);
1291     modCount = base.modCount;
1292     length += cSize;
1293     return true;
1294     }
1295     }
1296    
1297     public boolean equals(Object o) {
1298     synchronized(base) {return super.equals(o);}
1299     }
1300    
1301     public int hashCode() {
1302     synchronized(base) {return super.hashCode();}
1303     }
1304    
1305     public int indexOf(Object o) {
1306     synchronized(base) {return super.indexOf(o);}
1307     }
1308    
1309     public int lastIndexOf(Object o) {
1310     synchronized(base) {return super.lastIndexOf(o);}
1311     }
1312    
1313     public List<E> subList(int fromIndex, int toIndex) {
1314 jsr166 1.11 return new VectorSubList(base, this, fromIndex + baseOffset,
1315 dl 1.10 fromIndex, toIndex);
1316     }
1317    
1318     public Iterator<E> iterator() {
1319     synchronized(base) {
1320     return new VectorSubListIterator(this, 0);
1321     }
1322     }
1323 jsr166 1.11
1324 dl 1.10 public synchronized ListIterator<E> listIterator() {
1325     synchronized(base) {
1326     return new VectorSubListIterator(this, 0);
1327     }
1328     }
1329    
1330     public ListIterator<E> listIterator(int index) {
1331     synchronized(base) {
1332     if (index < 0 || index > length)
1333     throw indexError(index);
1334     return new VectorSubListIterator(this, index);
1335     }
1336     }
1337    
1338     /**
1339     * Same idea as VectorIterator, except routing structural
1340     * change operations through the sublist.
1341     */
1342     private static final class VectorSubListIterator<E> implements ListIterator<E> {
1343     final Vector<E> base; // base list
1344     final VectorSubList<E> outer; // Sublist creating this iteraor
1345     final int offset; // cursor offset wrt base
1346     int cursor; // Current index
1347     int fence; // Upper bound on cursor
1348     int lastRet; // Index of returned element, or -1
1349     int expectedModCount; // Expected modCount of base Vector
1350 jsr166 1.11
1351 dl 1.10 VectorSubListIterator(VectorSubList<E> list, int index) {
1352     this.lastRet = -1;
1353     this.cursor = index;
1354     this.outer = list;
1355     this.offset = list.baseOffset;
1356     this.fence = list.length;
1357     this.base = list.base;
1358     this.expectedModCount = base.modCount;
1359     }
1360 jsr166 1.11
1361 dl 1.10 public boolean hasNext() {
1362     return cursor < fence;
1363     }
1364 jsr166 1.11
1365 dl 1.10 public boolean hasPrevious() {
1366     return cursor > 0;
1367     }
1368 jsr166 1.11
1369 dl 1.10 public int nextIndex() {
1370     return cursor;
1371     }
1372 jsr166 1.11
1373 dl 1.10 public int previousIndex() {
1374     return cursor - 1;
1375     }
1376 jsr166 1.11
1377 dl 1.10 public E next() {
1378     int i = cursor;
1379     if (cursor >= fence)
1380     throw new NoSuchElementException();
1381     Object next = base.iteratorGet(i + offset, expectedModCount);
1382     lastRet = i;
1383     cursor = i + 1;
1384     return (E)next;
1385     }
1386 jsr166 1.11
1387 dl 1.10 public E previous() {
1388     int i = cursor - 1;
1389     if (i < 0)
1390     throw new NoSuchElementException();
1391     Object prev = base.iteratorGet(i + offset, expectedModCount);
1392     lastRet = i;
1393     cursor = i;
1394     return (E)prev;
1395     }
1396 jsr166 1.11
1397 dl 1.10 public void set(E e) {
1398     if (lastRet < 0)
1399     throw new IllegalStateException();
1400     if (base.modCount != expectedModCount)
1401     throw new ConcurrentModificationException();
1402     try {
1403     outer.set(lastRet, e);
1404     expectedModCount = base.modCount;
1405     } catch (IndexOutOfBoundsException ex) {
1406     throw new ConcurrentModificationException();
1407     }
1408     }
1409 jsr166 1.11
1410 dl 1.10 public void remove() {
1411     int i = lastRet;
1412     if (i < 0)
1413     throw new IllegalStateException();
1414     if (base.modCount != expectedModCount)
1415     throw new ConcurrentModificationException();
1416     try {
1417     outer.remove(i);
1418     if (i < cursor)
1419     cursor--;
1420     lastRet = -1;
1421     fence = outer.length;
1422     expectedModCount = base.modCount;
1423     } catch (IndexOutOfBoundsException ex) {
1424     throw new ConcurrentModificationException();
1425     }
1426     }
1427 jsr166 1.11
1428 dl 1.10 public void add(E e) {
1429     if (base.modCount != expectedModCount)
1430     throw new ConcurrentModificationException();
1431     try {
1432     int i = cursor;
1433     outer.add(i, e);
1434     cursor = i + 1;
1435     lastRet = -1;
1436     fence = outer.length;
1437     expectedModCount = base.modCount;
1438     } catch (IndexOutOfBoundsException ex) {
1439     throw new ConcurrentModificationException();
1440     }
1441     }
1442     }
1443     }
1444 dl 1.1 }
1445 dl 1.10
1446    
1447 jsr166 1.11