ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/Vector.java
Revision: 1.4
Committed: Mon Nov 28 03:28:25 2005 UTC (18 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.3: +3 -2 lines
Log Message:
whitespace

File Contents

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