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

File Contents

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