ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/Vector.java
Revision: 1.21
Committed: Sun May 20 07:54:01 2007 UTC (17 years ago) by jsr166
Branch: MAIN
Changes since 1.20: +21 -3 lines
Log Message:
License update

File Contents

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