[cvs] / jsr166 / src / main / java / util / Vector.java Repository:
ViewVC logotype

Annotation of /jsr166/src/main/java/util/Vector.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.21 - (view) (download)

1 : dl 1.1 /*
2 : jsr166 1.21 * Copyright 1994-2006 Sun Microsystems, Inc. All Rights Reserved.
3 :     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 : dl 1.1 *
5 : jsr166 1.21 * 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 : dl 1.1 */
25 :    
26 :     package java.util;
27 :    
28 :     /**
29 : jsr166 1.14 * The {@code Vector} class implements a growable array of
30 : dl 1.1 * objects. Like an array, it contains components that can be
31 :     * accessed using an integer index. However, the size of a
32 : jsr166 1.14 * {@code Vector} can grow or shrink as needed to accommodate
33 :     * adding and removing items after the {@code Vector} has been created.
34 : dl 1.1 *
35 : jsr166 1.9 * <p>Each vector tries to optimize storage management by maintaining a
36 : jsr166 1.14 * {@code capacity} and a {@code capacityIncrement}. The
37 :     * {@code capacity} is always at least as large as the vector
38 : dl 1.1 * 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 : jsr166 1.14 * {@code capacityIncrement}. An application can increase the
41 : dl 1.1 * capacity of a vector before inserting a large number of
42 : jsr166 1.9 * components; this reduces the amount of incremental reallocation.
43 : dl 1.1 *
44 : jsr166 1.9 * <p>The Iterators returned by Vector's iterator and listIterator
45 : dl 1.1 * 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 : jsr166 1.14 * throw {@code ConcurrentModificationException} on a best-effort basis.
58 : dl 1.1 * 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 : jsr166 1.9 * should be used only to detect bugs.</i>
61 : dl 1.1 *
62 : jsr166 1.9 * <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 : jsr166 1.13 * <a href="{@docRoot}/../technotes/guides/collections/index.html"> Java
65 : jsr166 1.9 * Collections Framework</a>. Unlike the new collection
66 :     * implementations, {@code Vector} is synchronized.
67 : dl 1.1 *
68 :     * @author Lee Boynton
69 :     * @author Jonathan Payne
70 : jsr166 1.12 * @version %I%, %G%
71 : dl 1.1 * @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 : jsr166 1.15 * and is at least large enough to contain all the vector's elements.
85 : dl 1.1 *
86 : jsr166 1.15 * <p>Any array elements following the last element in the Vector are null.
87 : dl 1.1 *
88 :     * @serial
89 :     */
90 :     protected Object[] elementData;
91 :    
92 :     /**
93 : jsr166 1.14 * 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 : dl 1.1 *
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 : jsr166 1.15 * @throws IllegalArgumentException if the specified initial capacity
122 :     * is negative
123 : dl 1.1 */
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 : jsr166 1.15 * @throws IllegalArgumentException if the specified initial capacity
139 :     * is negative
140 : dl 1.1 */
141 :     public Vector(int initialCapacity) {
142 :     this(initialCapacity, 0);
143 :     }
144 :    
145 :     /**
146 :     * Constructs an empty vector so that its internal data array
147 : jsr166 1.14 * has size {@code 10} and its standard capacity increment is
148 : dl 1.1 * 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 : jsr166 1.6 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 : dl 1.1 }
171 :    
172 :     /**
173 :     * Copies the components of this vector into the specified array.
174 : jsr166 1.14 * The item at index {@code k} in this vector is copied into
175 :     * component {@code k} of {@code anArray}.
176 : dl 1.1 *
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 : jsr166 1.14 * its internal data array, kept in the field {@code elementData},
194 : dl 1.1 * 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 : jsr166 1.14 * {@code minCapacity}, then its capacity is increased by replacing its
212 :     * internal data array, kept in the field {@code elementData}, with a
213 : dl 1.1 * larger one. The size of the new data array will be the old size plus
214 : jsr166 1.14 * {@code capacityIncrement}, unless the value of
215 :     * {@code capacityIncrement} is less than or equal to zero, in which case
216 : dl 1.1 * the new capacity will be twice the old capacity; but if this new size
217 : jsr166 1.14 * is still smaller than {@code minCapacity}, then the new capacity will
218 :     * be {@code minCapacity}.
219 : dl 1.1 *
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 : jsr166 1.15 * @see #ensureCapacity(int)
234 : dl 1.1 */
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 : jsr166 1.14 * current size, new {@code null} items are added to the end of
251 : dl 1.1 * the vector. If the new size is less than the current size, all
252 : jsr166 1.14 * components at index {@code newSize} and greater are discarded.
253 : dl 1.1 *
254 : jsr166 1.16 * @param newSize the new size of this vector
255 :     * @throws ArrayIndexOutOfBoundsException if the new size is negative
256 : dl 1.1 */
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 : jsr166 1.14 * data array, kept in the field {@code elementData}
274 : dl 1.1 * 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 : jsr166 1.14 * @return {@code true} if and only if this vector has
293 : dl 1.1 * no components, that is, its size is zero;
294 : jsr166 1.14 * {@code false} otherwise.
295 : dl 1.1 */
296 :     public synchronized boolean isEmpty() {
297 :     return elementCount == 0;
298 :     }
299 :    
300 :     /**
301 :     * Returns an enumeration of the components of this vector. The
302 : jsr166 1.14 * 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 : dl 1.1 *
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 : jsr166 1.14 * 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 : dl 1.1 * <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 : jsr166 1.14 * @return {@code true} if this vector contains the specified element
336 : dl 1.1 */
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 : jsr166 1.14 * More formally, returns the lowest index {@code i} such that
345 : dl 1.1 * <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 : jsr166 1.14 * this vector, searching forwards from {@code index}, or returns -1 if
359 : dl 1.1 * the element is not found.
360 : jsr166 1.14 * More formally, returns the lowest index {@code i} such that
361 : dl 1.1 * <tt>(i&nbsp;&gt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i))))</tt>,
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 : jsr166 1.14 * this vector at position {@code index} or later in the vector;
368 :     * {@code -1} if the element is not found.
369 : dl 1.1 * @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 : jsr166 1.14 * More formally, returns the highest index {@code i} such that
389 : dl 1.1 * <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 : jsr166 1.14 * this vector, searching backwards from {@code index}, or returns -1 if
403 : dl 1.1 * the element is not found.
404 : jsr166 1.14 * More formally, returns the highest index {@code i} such that
405 : dl 1.1 * <tt>(i&nbsp;&lt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i))))</tt>,
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 : jsr166 1.14 * less than or equal to {@code index} in this vector;
412 : dl 1.1 * -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 : jsr166 1.15 * Returns the component at the specified index.
434 : dl 1.1 *
435 : jsr166 1.15 * <p>This method is identical in functionality to the {@link #get(int)}
436 :     * method (which is part of the {@link List} interface).
437 : dl 1.1 *
438 :     * @param index an index into this vector
439 :     * @return the component at the specified index
440 : jsr166 1.15 * @throws ArrayIndexOutOfBoundsException if the index is out of range
441 :     * ({@code index < 0 || index >= size()})
442 : dl 1.1 */
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 : jsr166 1.14 * Returns the first component (the item at index {@code 0}) of
453 : dl 1.1 * this vector.
454 :     *
455 :     * @return the first component of this vector
456 : jsr166 1.15 * @throws NoSuchElementException if this vector has no components
457 : dl 1.1 */
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 : jsr166 1.15 * @throws NoSuchElementException if this vector is empty
471 : dl 1.1 */
472 :     public synchronized E lastElement() {
473 :     if (elementCount == 0) {
474 :     throw new NoSuchElementException();
475 :     }
476 :     return (E)elementData[elementCount - 1];
477 :     }
478 :    
479 :     /**
480 : jsr166 1.14 * Sets the component at the specified {@code index} of this
481 : dl 1.1 * vector to be the specified object. The previous component at that
482 : jsr166 1.16 * position is discarded.
483 : dl 1.1 *
484 : jsr166 1.16 * <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 : dl 1.1 *
487 : jsr166 1.17 * <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 : dl 1.1 *
494 :     * @param obj what the component is to be set to
495 :     * @param index the specified index
496 : jsr166 1.17 * @throws ArrayIndexOutOfBoundsException if the index is out of range
497 :     * ({@code index < 0 || index >= size()})
498 : dl 1.1 */
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 : jsr166 1.14 * {@code index} is shifted downward to have an index one
511 : dl 1.1 * smaller than the value it had previously. The size of this vector
512 : jsr166 1.15 * is decreased by {@code 1}.
513 : dl 1.1 *
514 : jsr166 1.15 * <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 : dl 1.1 *
517 : jsr166 1.17 * <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 : dl 1.1 *
522 :     * @param index the index of the object to remove
523 : jsr166 1.17 * @throws ArrayIndexOutOfBoundsException if the index is out of range
524 :     * ({@code index < 0 || index >= size()})
525 : dl 1.1 */
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 : jsr166 1.14 * specified {@code index}. Each component in this vector with
546 :     * an index greater or equal to the specified {@code index} is
547 : dl 1.1 * shifted upward to have an index one greater than the value it had
548 : jsr166 1.15 * previously.
549 : dl 1.1 *
550 : jsr166 1.15 * <p>The index must be a value greater than or equal to {@code 0}
551 : dl 1.1 * 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 : jsr166 1.15 * is appended to the Vector.)
554 : dl 1.1 *
555 : jsr166 1.17 * <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 : dl 1.1 *
561 :     * @param obj the component to insert
562 :     * @param index where to insert the new component
563 : jsr166 1.17 * @throws ArrayIndexOutOfBoundsException if the index is out of range
564 :     * ({@code index < 0 || index > size()})
565 : dl 1.1 */
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 : jsr166 1.16 * increased if its size becomes greater than its capacity.
582 : dl 1.1 *
583 : jsr166 1.17 * <p>This method is identical in functionality to the
584 : jsr166 1.18 * {@link #add(Object) add(E)}
585 :     * method (which is part of the {@link List} interface).
586 : dl 1.1 *
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 : jsr166 1.16 * than the value it had previously.
601 : dl 1.1 *
602 : jsr166 1.18 * <p>This method is identical in functionality to the
603 :     * {@link #remove(Object)} method (which is part of the
604 :     * {@link List} interface).
605 : dl 1.1 *
606 :     * @param obj the component to be removed
607 : jsr166 1.14 * @return {@code true} if the argument was a component of this
608 :     * vector; {@code false} otherwise.
609 : dl 1.1 */
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 : jsr166 1.17 * Removes all components from this vector and sets its size to zero.
622 : dl 1.1 *
623 : jsr166 1.17 * <p>This method is identical in functionality to the {@link #clear}
624 :     * method (which is part of the {@link List} interface).
625 : dl 1.1 */
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 : jsr166 1.14 * to the original internal data array of this {@code Vector} object.
639 : dl 1.1 *
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 : jsr166 1.16 * type of the specified array and the size of this Vector.
670 : dl 1.1 *
671 : jsr166 1.16 * <p>If the Vector fits in the specified array with room to spare
672 : dl 1.1 * (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 : jsr166 1.17 * @throws ArrayStoreException if the runtime type of a is not a supertype
683 : dl 1.1 * 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 : jsr166 1.17 * @throws ArrayIndexOutOfBoundsException if the index is out of range
707 :     * ({@code index < 0 || index >= size()})
708 : dl 1.1 * @since 1.2
709 :     */
710 :     public synchronized E 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 : jsr166 1.17 * @throws ArrayIndexOutOfBoundsException if the index is out of range
725 :     * ({@code index < 0 || index >= size()})
726 : dl 1.1 * @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 : jsr166 1.14 * @return {@code true} (as specified by {@link Collection#add})
742 : dl 1.1 * @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 : jsr166 1.14 * {@code (o==null ? get(i)==null : o.equals(get(i)))} (if such
756 : dl 1.1 * 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 : jsr166 1.17 * @throws ArrayIndexOutOfBoundsException if the index is out of range
774 :     * ({@code index < 0 || index > size()})
775 : dl 1.1 * @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 : jsr166 1.18 * @throws ArrayIndexOutOfBoundsException if the index is out of range
787 :     * ({@code index < 0 || index >= size()})
788 : dl 1.1 * @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 : jsr166 1.14 * @return {@code true} if this Vector changed as a result of the call
843 : dl 1.1 * @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 : jsr166 1.14 * @return {@code true} if this Vector changed as a result of the call
906 : jsr166 1.18 * @throws ArrayIndexOutOfBoundsException if the index is out of range
907 :     * ({@code index < 0 || index > size()})
908 : dl 1.1 * @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 : jsr166 1.14 * 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 : dl 1.1 * 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 : dl 1.10 * This call shortens the Vector by (toIndex - fromIndex) elements. (If
966 : dl 1.1 * 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 : jsr166 1.14 * Save the state of the {@code Vector} instance to a stream (that
985 : dl 1.1 * 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 : dl 1.10 * Obeys the general contract of {@link List#listIterator(int)}.
998 : dl 1.1 *
999 : dl 1.10 * <p>The list-iterator is <i>fail-fast</i>: if the list is structurally
1000 : dl 1.1 * modified at any time after the Iterator is created, in any way except
1001 : dl 1.10 * through the list-iterator's own {@code remove} or {@code add}
1002 : dl 1.1 * methods, the list-iterator will throw a
1003 : dl 1.10 * {@code ConcurrentModificationException}. Thus, in the face of
1004 : dl 1.1 * 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 : dl 1.10 * list-iterator (by a call to {@link ListIterator#next})
1010 :     * @return a list-iterator of the elements in this list (in proper
1011 : dl 1.1 * 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 : dl 1.10 return new VectorIterator(index, elementCount);
1018 : dl 1.1 }
1019 : jsr166 1.2
1020 : dl 1.1 /**
1021 : dl 1.3 * {@inheritDoc}
1022 :     */
1023 :     public synchronized ListIterator<E> listIterator() {
1024 : dl 1.10 return new VectorIterator(0, elementCount);
1025 : dl 1.3 }
1026 :    
1027 :     /**
1028 : dl 1.1 * 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 : dl 1.10 return new VectorIterator(0, elementCount);
1034 : dl 1.1 }
1035 :    
1036 :     /**
1037 : dl 1.10 * 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 : jsr166 1.19 * Locally performs bounds checks, but relies on outer Vector
1055 : dl 1.10 * to access elements under synchronization.
1056 : dl 1.1 */
1057 : dl 1.3 private final class VectorIterator implements ListIterator<E> {
1058 : dl 1.10 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 : dl 1.1 }
1069 :    
1070 :     public boolean hasNext() {
1071 : dl 1.10 return cursor < fence;
1072 : dl 1.1 }
1073 :    
1074 :     public boolean hasPrevious() {
1075 : dl 1.10 return cursor > 0;
1076 : dl 1.1 }
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 : dl 1.10 int i = cursor;
1088 :     if (i >= fence)
1089 : dl 1.3 throw new NoSuchElementException();
1090 : dl 1.10 Object next = Vector.this.iteratorGet(i, expectedModCount);
1091 :     lastRet = i;
1092 :     cursor = i + 1;
1093 :     return (E)next;
1094 : dl 1.1 }
1095 : jsr166 1.4
1096 : dl 1.10 public E previous() {
1097 :     int i = cursor - 1;
1098 :     if (i < 0)
1099 : dl 1.3 throw new NoSuchElementException();
1100 : dl 1.10 Object prev = Vector.this.iteratorGet(i, expectedModCount);
1101 :     lastRet = i;
1102 :     cursor = i;
1103 :     return (E)prev;
1104 : dl 1.1 }
1105 :    
1106 : dl 1.10 public void set(E e) {
1107 :     if (lastRet < 0)
1108 : dl 1.1 throw new IllegalStateException();
1109 : dl 1.10 if (Vector.this.modCount != expectedModCount)
1110 :     throw new ConcurrentModificationException();
1111 :     try {
1112 :     Vector.this.set(lastRet, e);
1113 :     expectedModCount = Vector.this.modCount;
1114 : jsr166 1.4 } catch (IndexOutOfBoundsException ex) {
1115 : dl 1.3 throw new ConcurrentModificationException();
1116 :     }
1117 : dl 1.1 }
1118 :    
1119 : dl 1.10 public void remove() {
1120 :     int i = lastRet;
1121 :     if (i < 0)
1122 : dl 1.1 throw new IllegalStateException();
1123 : dl 1.10 if (Vector.this.modCount != expectedModCount)
1124 : dl 1.3 throw new ConcurrentModificationException();
1125 : dl 1.10 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 : dl 1.3 } catch (IndexOutOfBoundsException ex) {
1133 :     throw new ConcurrentModificationException();
1134 :     }
1135 : dl 1.1 }
1136 :    
1137 :     public void add(E e) {
1138 : dl 1.10 if (Vector.this.modCount != expectedModCount)
1139 : dl 1.3 throw new ConcurrentModificationException();
1140 :     try {
1141 :     int i = cursor;
1142 : dl 1.10 Vector.this.add(i, e);
1143 : dl 1.3 cursor = i + 1;
1144 : dl 1.10 lastRet = -1;
1145 :     fence = Vector.this.size();
1146 :     expectedModCount = Vector.this.modCount;
1147 : dl 1.3 } catch (IndexOutOfBoundsException ex) {
1148 :     throw new ConcurrentModificationException();
1149 :     }
1150 : dl 1.1 }
1151 :     }
1152 : dl 1.10
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 : jsr166 1.16 * operations supported by this List.
1160 : dl 1.10 *
1161 : jsr166 1.16 * <p>This method eliminates the need for explicit range operations (of
1162 : dl 1.10 * 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 : jsr166 1.16 * a subList.
1172 : dl 1.10 *
1173 : jsr166 1.16 * <p>The semantics of the List returned by this method become undefined if
1174 : dl 1.10 * 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 : jsr166 1.18 * @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 : dl 1.10 */
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 : jsr166 1.11 VectorSubList(Vector<E> base, AbstractList<E> parent, int baseOffset,
1205 : dl 1.10 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 : jsr166 1.11 return new IndexOutOfBoundsException("Index: " + index +
1227 : dl 1.10 ", 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 : jsr166 1.11 parent.removeRange(fromIndex + parentOffset,
1288 : dl 1.10 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 : jsr166 1.11
1306 : dl 1.10 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 : jsr166 1.11 return new VectorSubList(base, this, fromIndex + baseOffset,
1333 : dl 1.10 fromIndex, toIndex);
1334 :     }
1335 :    
1336 :     public Iterator<E> iterator() {
1337 :     synchronized(base) {
1338 :     return new VectorSubListIterator(this, 0);
1339 :     }
1340 :     }
1341 : jsr166 1.11
1342 : dl 1.10 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 : jsr166 1.11
1369 : dl 1.10 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 : jsr166 1.11
1379 : dl 1.10 public boolean hasNext() {
1380 :     return cursor < fence;
1381 :     }
1382 : jsr166 1.11
1383 : dl 1.10 public boolean hasPrevious() {
1384 :     return cursor > 0;
1385 :     }
1386 : jsr166 1.11
1387 : dl 1.10 public int nextIndex() {
1388 :     return cursor;
1389 :     }
1390 : jsr166 1.11
1391 : dl 1.10 public int previousIndex() {
1392 :     return cursor - 1;
1393 :     }
1394 : jsr166 1.11
1395 : dl 1.10 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 : jsr166 1.11
1405 : dl 1.10 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 : jsr166 1.11
1415 : dl 1.10 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 : jsr166 1.11
1428 : dl 1.10 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 : jsr166 1.11
1446 : dl 1.10 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 : dl 1.1 }
1463 : dl 1.10
1464 :    
1465 : jsr166 1.11

Doug Lea
ViewVC Help
Powered by ViewVC 1.0.8