0001 /*
0002 * Copyright 1994-2007 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 package java.util;
0027
0028 /**
0029 * The {@code Vector} class implements a growable array of
0030 * objects. Like an array, it contains components that can be
0031 * accessed using an integer index. However, the size of a
0032 * {@code Vector} can grow or shrink as needed to accommodate
0033 * adding and removing items after the {@code Vector} has been created.
0034 *
0035 * <p>Each vector tries to optimize storage management by maintaining a
0036 * {@code capacity} and a {@code capacityIncrement}. The
0037 * {@code capacity} is always at least as large as the vector
0038 * size; it is usually larger because as components are added to the
0039 * vector, the vector's storage increases in chunks the size of
0040 * {@code capacityIncrement}. An application can increase the
0041 * capacity of a vector before inserting a large number of
0042 * components; this reduces the amount of incremental reallocation.
0043 *
0044 * <p><a name="fail-fast"/>
0045 * The iterators returned by this class's {@link #iterator() iterator} and
0046 * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
0047 * if the vector is structurally modified at any time after the iterator is
0048 * created, in any way except through the iterator's own
0049 * {@link ListIterator#remove() remove} or
0050 * {@link ListIterator#add(Object) add} methods, the iterator will throw a
0051 * {@link ConcurrentModificationException}. Thus, in the face of
0052 * concurrent modification, the iterator fails quickly and cleanly, rather
0053 * than risking arbitrary, non-deterministic behavior at an undetermined
0054 * time in the future. The {@link Enumeration Enumerations} returned by
0055 * the {@link #elements() elements} method are <em>not</em> fail-fast.
0056 *
0057 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
0058 * as it is, generally speaking, impossible to make any hard guarantees in the
0059 * presence of unsynchronized concurrent modification. Fail-fast iterators
0060 * throw {@code ConcurrentModificationException} on a best-effort basis.
0061 * Therefore, it would be wrong to write a program that depended on this
0062 * exception for its correctness: <i>the fail-fast behavior of iterators
0063 * should be used only to detect bugs.</i>
0064 *
0065 * <p>As of the Java 2 platform v1.2, this class was retrofitted to
0066 * implement the {@link List} interface, making it a member of the
0067 * <a href="{@docRoot}/../technotes/guides/collections/index.html"> Java
0068 * Collections Framework</a>. Unlike the new collection
0069 * implementations, {@code Vector} is synchronized.
0070 *
0071 * @author Lee Boynton
0072 * @author Jonathan Payne
0073 * @version 1.113, 06/11/07
0074 * @see Collection
0075 * @see List
0076 * @see ArrayList
0077 * @see LinkedList
0078 * @since JDK1.0
0079 */
0080 public class Vector<E> extends AbstractList<E> implements List<E>,
0081 RandomAccess, Cloneable, java.io.Serializable {
0082 /**
0083 * The array buffer into which the components of the vector are
0084 * stored. The capacity of the vector is the length of this array buffer,
0085 * and is at least large enough to contain all the vector's elements.
0086 *
0087 * <p>Any array elements following the last element in the Vector are null.
0088 *
0089 * @serial
0090 */
0091 protected Object[] elementData;
0092
0093 /**
0094 * The number of valid components in this {@code Vector} object.
0095 * Components {@code elementData[0]} through
0096 * {@code elementData[elementCount-1]} are the actual items.
0097 *
0098 * @serial
0099 */
0100 protected int elementCount;
0101
0102 /**
0103 * The amount by which the capacity of the vector is automatically
0104 * incremented when its size becomes greater than its capacity. If
0105 * the capacity increment is less than or equal to zero, the capacity
0106 * of the vector is doubled each time it needs to grow.
0107 *
0108 * @serial
0109 */
0110 protected int capacityIncrement;
0111
0112 /** use serialVersionUID from JDK 1.0.2 for interoperability */
0113 private static final long serialVersionUID = -2767605614048989439L;
0114
0115 /**
0116 * Constructs an empty vector with the specified initial capacity and
0117 * capacity increment.
0118 *
0119 * @param initialCapacity the initial capacity of the vector
0120 * @param capacityIncrement the amount by which the capacity is
0121 * increased when the vector overflows
0122 * @throws IllegalArgumentException if the specified initial capacity
0123 * is negative
0124 */
0125 public Vector(int initialCapacity, int capacityIncrement) {
0126 super ();
0127 if (initialCapacity < 0)
0128 throw new IllegalArgumentException("Illegal Capacity: "
0129 + initialCapacity);
0130 this .elementData = new Object[initialCapacity];
0131 this .capacityIncrement = capacityIncrement;
0132 }
0133
0134 /**
0135 * Constructs an empty vector with the specified initial capacity and
0136 * with its capacity increment equal to zero.
0137 *
0138 * @param initialCapacity the initial capacity of the vector
0139 * @throws IllegalArgumentException if the specified initial capacity
0140 * is negative
0141 */
0142 public Vector(int initialCapacity) {
0143 this (initialCapacity, 0);
0144 }
0145
0146 /**
0147 * Constructs an empty vector so that its internal data array
0148 * has size {@code 10} and its standard capacity increment is
0149 * zero.
0150 */
0151 public Vector() {
0152 this (10);
0153 }
0154
0155 /**
0156 * Constructs a vector containing the elements of the specified
0157 * collection, in the order they are returned by the collection's
0158 * iterator.
0159 *
0160 * @param c the collection whose elements are to be placed into this
0161 * vector
0162 * @throws NullPointerException if the specified collection is null
0163 * @since 1.2
0164 */
0165 public Vector(Collection<? extends E> c) {
0166 elementData = c.toArray();
0167 elementCount = elementData.length;
0168 // c.toArray might (incorrectly) not return Object[] (see 6260652)
0169 if (elementData.getClass() != Object[].class)
0170 elementData = Arrays.copyOf(elementData, elementCount,
0171 Object[].class);
0172 }
0173
0174 /**
0175 * Copies the components of this vector into the specified array.
0176 * The item at index {@code k} in this vector is copied into
0177 * component {@code k} of {@code anArray}.
0178 *
0179 * @param anArray the array into which the components get copied
0180 * @throws NullPointerException if the given array is null
0181 * @throws IndexOutOfBoundsException if the specified array is not
0182 * large enough to hold all the components of this vector
0183 * @throws ArrayStoreException if a component of this vector is not of
0184 * a runtime type that can be stored in the specified array
0185 * @see #toArray(Object[])
0186 */
0187 public synchronized void copyInto(Object[] anArray) {
0188 System.arraycopy(elementData, 0, anArray, 0, elementCount);
0189 }
0190
0191 /**
0192 * Trims the capacity of this vector to be the vector's current
0193 * size. If the capacity of this vector is larger than its current
0194 * size, then the capacity is changed to equal the size by replacing
0195 * its internal data array, kept in the field {@code elementData},
0196 * with a smaller one. An application can use this operation to
0197 * minimize the storage of a vector.
0198 */
0199 public synchronized void trimToSize() {
0200 modCount++;
0201 int oldCapacity = elementData.length;
0202 if (elementCount < oldCapacity) {
0203 elementData = Arrays.copyOf(elementData, elementCount);
0204 }
0205 }
0206
0207 /**
0208 * Increases the capacity of this vector, if necessary, to ensure
0209 * that it can hold at least the number of components specified by
0210 * the minimum capacity argument.
0211 *
0212 * <p>If the current capacity of this vector is less than
0213 * {@code minCapacity}, then its capacity is increased by replacing its
0214 * internal data array, kept in the field {@code elementData}, with a
0215 * larger one. The size of the new data array will be the old size plus
0216 * {@code capacityIncrement}, unless the value of
0217 * {@code capacityIncrement} is less than or equal to zero, in which case
0218 * the new capacity will be twice the old capacity; but if this new size
0219 * is still smaller than {@code minCapacity}, then the new capacity will
0220 * be {@code minCapacity}.
0221 *
0222 * @param minCapacity the desired minimum capacity
0223 */
0224 public synchronized void ensureCapacity(int minCapacity) {
0225 modCount++;
0226 ensureCapacityHelper(minCapacity);
0227 }
0228
0229 /**
0230 * This implements the unsynchronized semantics of ensureCapacity.
0231 * Synchronized methods in this class can internally call this
0232 * method for ensuring capacity without incurring the cost of an
0233 * extra synchronization.
0234 *
0235 * @see #ensureCapacity(int)
0236 */
0237 private void ensureCapacityHelper(int minCapacity) {
0238 int oldCapacity = elementData.length;
0239 if (minCapacity > oldCapacity) {
0240 Object[] oldData = elementData;
0241 int newCapacity = (capacityIncrement > 0) ? (oldCapacity + capacityIncrement)
0242 : (oldCapacity * 2);
0243 if (newCapacity < minCapacity) {
0244 newCapacity = minCapacity;
0245 }
0246 elementData = Arrays.copyOf(elementData, newCapacity);
0247 }
0248 }
0249
0250 /**
0251 * Sets the size of this vector. If the new size is greater than the
0252 * current size, new {@code null} items are added to the end of
0253 * the vector. If the new size is less than the current size, all
0254 * components at index {@code newSize} and greater are discarded.
0255 *
0256 * @param newSize the new size of this vector
0257 * @throws ArrayIndexOutOfBoundsException if the new size is negative
0258 */
0259 public synchronized void setSize(int newSize) {
0260 modCount++;
0261 if (newSize > elementCount) {
0262 ensureCapacityHelper(newSize);
0263 } else {
0264 for (int i = newSize; i < elementCount; i++) {
0265 elementData[i] = null;
0266 }
0267 }
0268 elementCount = newSize;
0269 }
0270
0271 /**
0272 * Returns the current capacity of this vector.
0273 *
0274 * @return the current capacity (the length of its internal
0275 * data array, kept in the field {@code elementData}
0276 * of this vector)
0277 */
0278 public synchronized int capacity() {
0279 return elementData.length;
0280 }
0281
0282 /**
0283 * Returns the number of components in this vector.
0284 *
0285 * @return the number of components in this vector
0286 */
0287 public synchronized int size() {
0288 return elementCount;
0289 }
0290
0291 /**
0292 * Tests if this vector has no components.
0293 *
0294 * @return {@code true} if and only if this vector has
0295 * no components, that is, its size is zero;
0296 * {@code false} otherwise.
0297 */
0298 public synchronized boolean isEmpty() {
0299 return elementCount == 0;
0300 }
0301
0302 /**
0303 * Returns an enumeration of the components of this vector. The
0304 * returned {@code Enumeration} object will generate all items in
0305 * this vector. The first item generated is the item at index {@code 0},
0306 * then the item at index {@code 1}, and so on.
0307 *
0308 * @return an enumeration of the components of this vector
0309 * @see Iterator
0310 */
0311 public Enumeration<E> elements() {
0312 return new Enumeration<E>() {
0313 int count = 0;
0314
0315 public boolean hasMoreElements() {
0316 return count < elementCount;
0317 }
0318
0319 public E nextElement() {
0320 synchronized (Vector.this ) {
0321 if (count < elementCount) {
0322 return elementData(count++);
0323 }
0324 }
0325 throw new NoSuchElementException("Vector Enumeration");
0326 }
0327 };
0328 }
0329
0330 /**
0331 * Returns {@code true} if this vector contains the specified element.
0332 * More formally, returns {@code true} if and only if this vector
0333 * contains at least one element {@code e} such that
0334 * <tt>(o==null ? e==null : o.equals(e))</tt>.
0335 *
0336 * @param o element whose presence in this vector is to be tested
0337 * @return {@code true} if this vector contains the specified element
0338 */
0339 public boolean contains(Object o) {
0340 return indexOf(o, 0) >= 0;
0341 }
0342
0343 /**
0344 * Returns the index of the first occurrence of the specified element
0345 * in this vector, or -1 if this vector does not contain the element.
0346 * More formally, returns the lowest index {@code i} such that
0347 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
0348 * or -1 if there is no such index.
0349 *
0350 * @param o element to search for
0351 * @return the index of the first occurrence of the specified element in
0352 * this vector, or -1 if this vector does not contain the element
0353 */
0354 public int indexOf(Object o) {
0355 return indexOf(o, 0);
0356 }
0357
0358 /**
0359 * Returns the index of the first occurrence of the specified element in
0360 * this vector, searching forwards from {@code index}, or returns -1 if
0361 * the element is not found.
0362 * More formally, returns the lowest index {@code i} such that
0363 * <tt>(i >= index && (o==null ? get(i)==null : o.equals(get(i))))</tt>,
0364 * or -1 if there is no such index.
0365 *
0366 * @param o element to search for
0367 * @param index index to start searching from
0368 * @return the index of the first occurrence of the element in
0369 * this vector at position {@code index} or later in the vector;
0370 * {@code -1} if the element is not found.
0371 * @throws IndexOutOfBoundsException if the specified index is negative
0372 * @see Object#equals(Object)
0373 */
0374 public synchronized int indexOf(Object o, int index) {
0375 if (o == null) {
0376 for (int i = index; i < elementCount; i++)
0377 if (elementData[i] == null)
0378 return i;
0379 } else {
0380 for (int i = index; i < elementCount; i++)
0381 if (o.equals(elementData[i]))
0382 return i;
0383 }
0384 return -1;
0385 }
0386
0387 /**
0388 * Returns the index of the last occurrence of the specified element
0389 * in this vector, or -1 if this vector does not contain the element.
0390 * More formally, returns the highest index {@code i} such that
0391 * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
0392 * or -1 if there is no such index.
0393 *
0394 * @param o element to search for
0395 * @return the index of the last occurrence of the specified element in
0396 * this vector, or -1 if this vector does not contain the element
0397 */
0398 public synchronized int lastIndexOf(Object o) {
0399 return lastIndexOf(o, elementCount - 1);
0400 }
0401
0402 /**
0403 * Returns the index of the last occurrence of the specified element in
0404 * this vector, searching backwards from {@code index}, or returns -1 if
0405 * the element is not found.
0406 * More formally, returns the highest index {@code i} such that
0407 * <tt>(i <= index && (o==null ? get(i)==null : o.equals(get(i))))</tt>,
0408 * or -1 if there is no such index.
0409 *
0410 * @param o element to search for
0411 * @param index index to start searching backwards from
0412 * @return the index of the last occurrence of the element at position
0413 * less than or equal to {@code index} in this vector;
0414 * -1 if the element is not found.
0415 * @throws IndexOutOfBoundsException if the specified index is greater
0416 * than or equal to the current size of this vector
0417 */
0418 public synchronized int lastIndexOf(Object o, int index) {
0419 if (index >= elementCount)
0420 throw new IndexOutOfBoundsException(index + " >= "
0421 + elementCount);
0422
0423 if (o == null) {
0424 for (int i = index; i >= 0; i--)
0425 if (elementData[i] == null)
0426 return i;
0427 } else {
0428 for (int i = index; i >= 0; i--)
0429 if (o.equals(elementData[i]))
0430 return i;
0431 }
0432 return -1;
0433 }
0434
0435 /**
0436 * Returns the component at the specified index.
0437 *
0438 * <p>This method is identical in functionality to the {@link #get(int)}
0439 * method (which is part of the {@link List} interface).
0440 *
0441 * @param index an index into this vector
0442 * @return the component at the specified index
0443 * @throws ArrayIndexOutOfBoundsException if the index is out of range
0444 * ({@code index < 0 || index >= size()})
0445 */
0446 public synchronized E elementAt(int index) {
0447 if (index >= elementCount) {
0448 throw new ArrayIndexOutOfBoundsException(index + " >= "
0449 + elementCount);
0450 }
0451
0452 return elementData(index);
0453 }
0454
0455 /**
0456 * Returns the first component (the item at index {@code 0}) of
0457 * this vector.
0458 *
0459 * @return the first component of this vector
0460 * @throws NoSuchElementException if this vector has no components
0461 */
0462 public synchronized E firstElement() {
0463 if (elementCount == 0) {
0464 throw new NoSuchElementException();
0465 }
0466 return elementData(0);
0467 }
0468
0469 /**
0470 * Returns the last component of the vector.
0471 *
0472 * @return the last component of the vector, i.e., the component at index
0473 * <code>size() - 1</code>.
0474 * @throws NoSuchElementException if this vector is empty
0475 */
0476 public synchronized E lastElement() {
0477 if (elementCount == 0) {
0478 throw new NoSuchElementException();
0479 }
0480 return elementData(elementCount - 1);
0481 }
0482
0483 /**
0484 * Sets the component at the specified {@code index} of this
0485 * vector to be the specified object. The previous component at that
0486 * position is discarded.
0487 *
0488 * <p>The index must be a value greater than or equal to {@code 0}
0489 * and less than the current size of the vector.
0490 *
0491 * <p>This method is identical in functionality to the
0492 * {@link #set(int, Object) set(int, E)}
0493 * method (which is part of the {@link List} interface). Note that the
0494 * {@code set} method reverses the order of the parameters, to more closely
0495 * match array usage. Note also that the {@code set} method returns the
0496 * old value that was stored at the specified position.
0497 *
0498 * @param obj what the component is to be set to
0499 * @param index the specified index
0500 * @throws ArrayIndexOutOfBoundsException if the index is out of range
0501 * ({@code index < 0 || index >= size()})
0502 */
0503 public synchronized void setElementAt(E obj, int index) {
0504 if (index >= elementCount) {
0505 throw new ArrayIndexOutOfBoundsException(index + " >= "
0506 + elementCount);
0507 }
0508 elementData[index] = obj;
0509 }
0510
0511 /**
0512 * Deletes the component at the specified index. Each component in
0513 * this vector with an index greater or equal to the specified
0514 * {@code index} is shifted downward to have an index one
0515 * smaller than the value it had previously. The size of this vector
0516 * is decreased by {@code 1}.
0517 *
0518 * <p>The index must be a value greater than or equal to {@code 0}
0519 * and less than the current size of the vector.
0520 *
0521 * <p>This method is identical in functionality to the {@link #remove(int)}
0522 * method (which is part of the {@link List} interface). Note that the
0523 * {@code remove} method returns the old value that was stored at the
0524 * specified position.
0525 *
0526 * @param index the index of the object to remove
0527 * @throws ArrayIndexOutOfBoundsException if the index is out of range
0528 * ({@code index < 0 || index >= size()})
0529 */
0530 public synchronized void removeElementAt(int index) {
0531 modCount++;
0532 if (index >= elementCount) {
0533 throw new ArrayIndexOutOfBoundsException(index + " >= "
0534 + elementCount);
0535 } else if (index < 0) {
0536 throw new ArrayIndexOutOfBoundsException(index);
0537 }
0538 int j = elementCount - index - 1;
0539 if (j > 0) {
0540 System.arraycopy(elementData, index + 1, elementData,
0541 index, j);
0542 }
0543 elementCount--;
0544 elementData[elementCount] = null; /* to let gc do its work */
0545 }
0546
0547 /**
0548 * Inserts the specified object as a component in this vector at the
0549 * specified {@code index}. Each component in this vector with
0550 * an index greater or equal to the specified {@code index} is
0551 * shifted upward to have an index one greater than the value it had
0552 * previously.
0553 *
0554 * <p>The index must be a value greater than or equal to {@code 0}
0555 * and less than or equal to the current size of the vector. (If the
0556 * index is equal to the current size of the vector, the new element
0557 * is appended to the Vector.)
0558 *
0559 * <p>This method is identical in functionality to the
0560 * {@link #add(int, Object) add(int, E)}
0561 * method (which is part of the {@link List} interface). Note that the
0562 * {@code add} method reverses the order of the parameters, to more closely
0563 * match array usage.
0564 *
0565 * @param obj the component to insert
0566 * @param index where to insert the new component
0567 * @throws ArrayIndexOutOfBoundsException if the index is out of range
0568 * ({@code index < 0 || index > size()})
0569 */
0570 public synchronized void insertElementAt(E obj, int index) {
0571 modCount++;
0572 if (index > elementCount) {
0573 throw new ArrayIndexOutOfBoundsException(index + " > "
0574 + elementCount);
0575 }
0576 ensureCapacityHelper(elementCount + 1);
0577 System.arraycopy(elementData, index, elementData, index + 1,
0578 elementCount - index);
0579 elementData[index] = obj;
0580 elementCount++;
0581 }
0582
0583 /**
0584 * Adds the specified component to the end of this vector,
0585 * increasing its size by one. The capacity of this vector is
0586 * increased if its size becomes greater than its capacity.
0587 *
0588 * <p>This method is identical in functionality to the
0589 * {@link #add(Object) add(E)}
0590 * method (which is part of the {@link List} interface).
0591 *
0592 * @param obj the component to be added
0593 */
0594 public synchronized void addElement(E obj) {
0595 modCount++;
0596 ensureCapacityHelper(elementCount + 1);
0597 elementData[elementCount++] = obj;
0598 }
0599
0600 /**
0601 * Removes the first (lowest-indexed) occurrence of the argument
0602 * from this vector. If the object is found in this vector, each
0603 * component in the vector with an index greater or equal to the
0604 * object's index is shifted downward to have an index one smaller
0605 * than the value it had previously.
0606 *
0607 * <p>This method is identical in functionality to the
0608 * {@link #remove(Object)} method (which is part of the
0609 * {@link List} interface).
0610 *
0611 * @param obj the component to be removed
0612 * @return {@code true} if the argument was a component of this
0613 * vector; {@code false} otherwise.
0614 */
0615 public synchronized boolean removeElement(Object obj) {
0616 modCount++;
0617 int i = indexOf(obj);
0618 if (i >= 0) {
0619 removeElementAt(i);
0620 return true;
0621 }
0622 return false;
0623 }
0624
0625 /**
0626 * Removes all components from this vector and sets its size to zero.
0627 *
0628 * <p>This method is identical in functionality to the {@link #clear}
0629 * method (which is part of the {@link List} interface).
0630 */
0631 public synchronized void removeAllElements() {
0632 modCount++;
0633 // Let gc do its work
0634 for (int i = 0; i < elementCount; i++)
0635 elementData[i] = null;
0636
0637 elementCount = 0;
0638 }
0639
0640 /**
0641 * Returns a clone of this vector. The copy will contain a
0642 * reference to a clone of the internal data array, not a reference
0643 * to the original internal data array of this {@code Vector} object.
0644 *
0645 * @return a clone of this vector
0646 */
0647 public synchronized Object clone() {
0648 try {
0649 @SuppressWarnings("unchecked")
0650 Vector<E> v = (Vector<E>) super .clone();
0651 v.elementData = Arrays.copyOf(elementData, elementCount);
0652 v.modCount = 0;
0653 return v;
0654 } catch (CloneNotSupportedException e) {
0655 // this shouldn't happen, since we are Cloneable
0656 throw new InternalError();
0657 }
0658 }
0659
0660 /**
0661 * Returns an array containing all of the elements in this Vector
0662 * in the correct order.
0663 *
0664 * @since 1.2
0665 */
0666 public synchronized Object[] toArray() {
0667 return Arrays.copyOf(elementData, elementCount);
0668 }
0669
0670 /**
0671 * Returns an array containing all of the elements in this Vector in the
0672 * correct order; the runtime type of the returned array is that of the
0673 * specified array. If the Vector fits in the specified array, it is
0674 * returned therein. Otherwise, a new array is allocated with the runtime
0675 * type of the specified array and the size of this Vector.
0676 *
0677 * <p>If the Vector fits in the specified array with room to spare
0678 * (i.e., the array has more elements than the Vector),
0679 * the element in the array immediately following the end of the
0680 * Vector is set to null. (This is useful in determining the length
0681 * of the Vector <em>only</em> if the caller knows that the Vector
0682 * does not contain any null elements.)
0683 *
0684 * @param a the array into which the elements of the Vector are to
0685 * be stored, if it is big enough; otherwise, a new array of the
0686 * same runtime type is allocated for this purpose.
0687 * @return an array containing the elements of the Vector
0688 * @throws ArrayStoreException if the runtime type of a is not a supertype
0689 * of the runtime type of every element in this Vector
0690 * @throws NullPointerException if the given array is null
0691 * @since 1.2
0692 */
0693 @SuppressWarnings("unchecked")
0694 public synchronized <T> T[] toArray(T[] a) {
0695 if (a.length < elementCount)
0696 return (T[]) Arrays.copyOf(elementData, elementCount, a
0697 .getClass());
0698
0699 System.arraycopy(elementData, 0, a, 0, elementCount);
0700
0701 if (a.length > elementCount)
0702 a[elementCount] = null;
0703
0704 return a;
0705 }
0706
0707 // Positional Access Operations
0708
0709 @SuppressWarnings("unchecked")
0710 E elementData(int index) {
0711 return (E) elementData[index];
0712 }
0713
0714 /**
0715 * Returns the element at the specified position in this Vector.
0716 *
0717 * @param index index of the element to return
0718 * @return object at the specified index
0719 * @throws ArrayIndexOutOfBoundsException if the index is out of range
0720 * ({@code index < 0 || index >= size()})
0721 * @since 1.2
0722 */
0723 public synchronized E get(int index) {
0724 if (index >= elementCount)
0725 throw new ArrayIndexOutOfBoundsException(index);
0726
0727 return elementData(index);
0728 }
0729
0730 /**
0731 * Replaces the element at the specified position in this Vector with the
0732 * specified element.
0733 *
0734 * @param index index of the element to replace
0735 * @param element element to be stored at the specified position
0736 * @return the element previously at the specified position
0737 * @throws ArrayIndexOutOfBoundsException if the index is out of range
0738 * ({@code index < 0 || index >= size()})
0739 * @since 1.2
0740 */
0741 public synchronized E set(int index, E element) {
0742 if (index >= elementCount)
0743 throw new ArrayIndexOutOfBoundsException(index);
0744
0745 E oldValue = elementData(index);
0746 elementData[index] = element;
0747 return oldValue;
0748 }
0749
0750 /**
0751 * Appends the specified element to the end of this Vector.
0752 *
0753 * @param e element to be appended to this Vector
0754 * @return {@code true} (as specified by {@link Collection#add})
0755 * @since 1.2
0756 */
0757 public synchronized boolean add(E e) {
0758 modCount++;
0759 ensureCapacityHelper(elementCount + 1);
0760 elementData[elementCount++] = e;
0761 return true;
0762 }
0763
0764 /**
0765 * Removes the first occurrence of the specified element in this Vector
0766 * If the Vector does not contain the element, it is unchanged. More
0767 * formally, removes the element with the lowest index i such that
0768 * {@code (o==null ? get(i)==null : o.equals(get(i)))} (if such
0769 * an element exists).
0770 *
0771 * @param o element to be removed from this Vector, if present
0772 * @return true if the Vector contained the specified element
0773 * @since 1.2
0774 */
0775 public boolean remove(Object o) {
0776 return removeElement(o);
0777 }
0778
0779 /**
0780 * Inserts the specified element at the specified position in this Vector.
0781 * Shifts the element currently at that position (if any) and any
0782 * subsequent elements to the right (adds one to their indices).
0783 *
0784 * @param index index at which the specified element is to be inserted
0785 * @param element element to be inserted
0786 * @throws ArrayIndexOutOfBoundsException if the index is out of range
0787 * ({@code index < 0 || index > size()})
0788 * @since 1.2
0789 */
0790 public void add(int index, E element) {
0791 insertElementAt(element, index);
0792 }
0793
0794 /**
0795 * Removes the element at the specified position in this Vector.
0796 * Shifts any subsequent elements to the left (subtracts one from their
0797 * indices). Returns the element that was removed from the Vector.
0798 *
0799 * @throws ArrayIndexOutOfBoundsException if the index is out of range
0800 * ({@code index < 0 || index >= size()})
0801 * @param index the index of the element to be removed
0802 * @return element that was removed
0803 * @since 1.2
0804 */
0805 public synchronized E remove(int index) {
0806 modCount++;
0807 if (index >= elementCount)
0808 throw new ArrayIndexOutOfBoundsException(index);
0809 E oldValue = elementData(index);
0810
0811 int numMoved = elementCount - index - 1;
0812 if (numMoved > 0)
0813 System.arraycopy(elementData, index + 1, elementData,
0814 index, numMoved);
0815 elementData[--elementCount] = null; // Let gc do its work
0816
0817 return oldValue;
0818 }
0819
0820 /**
0821 * Removes all of the elements from this Vector. The Vector will
0822 * be empty after this call returns (unless it throws an exception).
0823 *
0824 * @since 1.2
0825 */
0826 public void clear() {
0827 removeAllElements();
0828 }
0829
0830 // Bulk Operations
0831
0832 /**
0833 * Returns true if this Vector contains all of the elements in the
0834 * specified Collection.
0835 *
0836 * @param c a collection whose elements will be tested for containment
0837 * in this Vector
0838 * @return true if this Vector contains all of the elements in the
0839 * specified collection
0840 * @throws NullPointerException if the specified collection is null
0841 */
0842 public synchronized boolean containsAll(Collection<?> c) {
0843 return super .containsAll(c);
0844 }
0845
0846 /**
0847 * Appends all of the elements in the specified Collection to the end of
0848 * this Vector, in the order that they are returned by the specified
0849 * Collection's Iterator. The behavior of this operation is undefined if
0850 * the specified Collection is modified while the operation is in progress.
0851 * (This implies that the behavior of this call is undefined if the
0852 * specified Collection is this Vector, and this Vector is nonempty.)
0853 *
0854 * @param c elements to be inserted into this Vector
0855 * @return {@code true} if this Vector changed as a result of the call
0856 * @throws NullPointerException if the specified collection is null
0857 * @since 1.2
0858 */
0859 public synchronized boolean addAll(Collection<? extends E> c) {
0860 modCount++;
0861 Object[] a = c.toArray();
0862 int numNew = a.length;
0863 ensureCapacityHelper(elementCount + numNew);
0864 System.arraycopy(a, 0, elementData, elementCount, numNew);
0865 elementCount += numNew;
0866 return numNew != 0;
0867 }
0868
0869 /**
0870 * Removes from this Vector all of its elements that are contained in the
0871 * specified Collection.
0872 *
0873 * @param c a collection of elements to be removed from the Vector
0874 * @return true if this Vector changed as a result of the call
0875 * @throws ClassCastException if the types of one or more elements
0876 * in this vector are incompatible with the specified
0877 * collection (optional)
0878 * @throws NullPointerException if this vector contains one or more null
0879 * elements and the specified collection does not support null
0880 * elements (optional), or if the specified collection is null
0881 * @since 1.2
0882 */
0883 public synchronized boolean removeAll(Collection<?> c) {
0884 return super .removeAll(c);
0885 }
0886
0887 /**
0888 * Retains only the elements in this Vector that are contained in the
0889 * specified Collection. In other words, removes from this Vector all
0890 * of its elements that are not contained in the specified Collection.
0891 *
0892 * @param c a collection of elements to be retained in this Vector
0893 * (all other elements are removed)
0894 * @return true if this Vector changed as a result of the call
0895 * @throws ClassCastException if the types of one or more elements
0896 * in this vector are incompatible with the specified
0897 * collection (optional)
0898 * @throws NullPointerException if this vector contains one or more null
0899 * elements and the specified collection does not support null
0900 * elements (optional), or if the specified collection is null
0901 * @since 1.2
0902 */
0903 public synchronized boolean retainAll(Collection<?> c) {
0904 return super .retainAll(c);
0905 }
0906
0907 /**
0908 * Inserts all of the elements in the specified Collection into this
0909 * Vector at the specified position. Shifts the element currently at
0910 * that position (if any) and any subsequent elements to the right
0911 * (increases their indices). The new elements will appear in the Vector
0912 * in the order that they are returned by the specified Collection's
0913 * iterator.
0914 *
0915 * @param index index at which to insert the first element from the
0916 * specified collection
0917 * @param c elements to be inserted into this Vector
0918 * @return {@code true} if this Vector changed as a result of the call
0919 * @throws ArrayIndexOutOfBoundsException if the index is out of range
0920 * ({@code index < 0 || index > size()})
0921 * @throws NullPointerException if the specified collection is null
0922 * @since 1.2
0923 */
0924 public synchronized boolean addAll(int index,
0925 Collection<? extends E> c) {
0926 modCount++;
0927 if (index < 0 || index > elementCount)
0928 throw new ArrayIndexOutOfBoundsException(index);
0929
0930 Object[] a = c.toArray();
0931 int numNew = a.length;
0932 ensureCapacityHelper(elementCount + numNew);
0933
0934 int numMoved = elementCount - index;
0935 if (numMoved > 0)
0936 System.arraycopy(elementData, index, elementData, index
0937 + numNew, numMoved);
0938
0939 System.arraycopy(a, 0, elementData, index, numNew);
0940 elementCount += numNew;
0941 return numNew != 0;
0942 }
0943
0944 /**
0945 * Compares the specified Object with this Vector for equality. Returns
0946 * true if and only if the specified Object is also a List, both Lists
0947 * have the same size, and all corresponding pairs of elements in the two
0948 * Lists are <em>equal</em>. (Two elements {@code e1} and
0949 * {@code e2} are <em>equal</em> if {@code (e1==null ? e2==null :
0950 * e1.equals(e2))}.) In other words, two Lists are defined to be
0951 * equal if they contain the same elements in the same order.
0952 *
0953 * @param o the Object to be compared for equality with this Vector
0954 * @return true if the specified Object is equal to this Vector
0955 */
0956 public synchronized boolean equals(Object o) {
0957 return super .equals(o);
0958 }
0959
0960 /**
0961 * Returns the hash code value for this Vector.
0962 */
0963 public synchronized int hashCode() {
0964 return super .hashCode();
0965 }
0966
0967 /**
0968 * Returns a string representation of this Vector, containing
0969 * the String representation of each element.
0970 */
0971 public synchronized String toString() {
0972 return super .toString();
0973 }
0974
0975 /**
0976 * Returns a view of the portion of this List between fromIndex,
0977 * inclusive, and toIndex, exclusive. (If fromIndex and toIndex are
0978 * equal, the returned List is empty.) The returned List is backed by this
0979 * List, so changes in the returned List are reflected in this List, and
0980 * vice-versa. The returned List supports all of the optional List
0981 * operations supported by this List.
0982 *
0983 * <p>This method eliminates the need for explicit range operations (of
0984 * the sort that commonly exist for arrays). Any operation that expects
0985 * a List can be used as a range operation by operating on a subList view
0986 * instead of a whole List. For example, the following idiom
0987 * removes a range of elements from a List:
0988 * <pre>
0989 * list.subList(from, to).clear();
0990 * </pre>
0991 * Similar idioms may be constructed for indexOf and lastIndexOf,
0992 * and all of the algorithms in the Collections class can be applied to
0993 * a subList.
0994 *
0995 * <p>The semantics of the List returned by this method become undefined if
0996 * the backing list (i.e., this List) is <i>structurally modified</i> in
0997 * any way other than via the returned List. (Structural modifications are
0998 * those that change the size of the List, or otherwise perturb it in such
0999 * a fashion that iterations in progress may yield incorrect results.)
1000 *
1001 * @param fromIndex low endpoint (inclusive) of the subList
1002 * @param toIndex high endpoint (exclusive) of the subList
1003 * @return a view of the specified range within this List
1004 * @throws IndexOutOfBoundsException if an endpoint index value is out of range
1005 * {@code (fromIndex < 0 || toIndex > size)}
1006 * @throws IllegalArgumentException if the endpoint indices are out of order
1007 * {@code (fromIndex > toIndex)}
1008 */
1009 public synchronized List<E> subList(int fromIndex, int toIndex) {
1010 return Collections.synchronizedList(super .subList(fromIndex,
1011 toIndex), this );
1012 }
1013
1014 /**
1015 * Removes from this list all of the elements whose index is between
1016 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
1017 * Shifts any succeeding elements to the left (reduces their index).
1018 * This call shortens the list by {@code (toIndex - fromIndex)} elements.
1019 * (If {@code toIndex==fromIndex}, this operation has no effect.)
1020 */
1021 protected synchronized void removeRange(int fromIndex, int toIndex) {
1022 modCount++;
1023 int numMoved = elementCount - toIndex;
1024 System.arraycopy(elementData, toIndex, elementData, fromIndex,
1025 numMoved);
1026
1027 // Let gc do its work
1028 int newElementCount = elementCount - (toIndex - fromIndex);
1029 while (elementCount != newElementCount)
1030 elementData[--elementCount] = null;
1031 }
1032
1033 /**
1034 * Save the state of the {@code Vector} instance to a stream (that
1035 * is, serialize it). This method is present merely for synchronization.
1036 * It just calls the default writeObject method.
1037 */
1038 private synchronized void writeObject(java.io.ObjectOutputStream s)
1039 throws java.io.IOException {
1040 s.defaultWriteObject();
1041 }
1042
1043 /**
1044 * Returns a list iterator over the elements in this list (in proper
1045 * sequence), starting at the specified position in the list.
1046 * The specified index indicates the first element that would be
1047 * returned by an initial call to {@link ListIterator#next next}.
1048 * An initial call to {@link ListIterator#previous previous} would
1049 * return the element with the specified index minus one.
1050 *
1051 * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
1052 *
1053 * @throws IndexOutOfBoundsException {@inheritDoc}
1054 */
1055 public synchronized ListIterator<E> listIterator(int index) {
1056 if (index < 0 || index > elementCount)
1057 throw new IndexOutOfBoundsException("Index: " + index);
1058 return new ListItr(index);
1059 }
1060
1061 /**
1062 * Returns a list iterator over the elements in this list (in proper
1063 * sequence).
1064 *
1065 * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
1066 *
1067 * @see #listIterator(int)
1068 */
1069 public synchronized ListIterator<E> listIterator() {
1070 return new ListItr(0);
1071 }
1072
1073 /**
1074 * Returns an iterator over the elements in this list in proper sequence.
1075 *
1076 * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
1077 *
1078 * @return an iterator over the elements in this list in proper sequence
1079 */
1080 public synchronized Iterator<E> iterator() {
1081 return new Itr();
1082 }
1083
1084 /**
1085 * An optimized version of AbstractList.Itr
1086 */
1087 private class Itr implements Iterator<E> {
1088 int cursor; // index of next element to return
1089 int lastRet = -1; // index of last element returned; -1 if no such
1090 int expectedModCount = modCount;
1091
1092 public boolean hasNext() {
1093 // Racy but within spec, since modifications are checked
1094 // within or after synchronization in next/previous
1095 return cursor != elementCount;
1096 }
1097
1098 public E next() {
1099 synchronized (Vector.this ) {
1100 checkForComodification();
1101 int i = cursor;
1102 if (i >= elementCount)
1103 throw new NoSuchElementException();
1104 cursor = i + 1;
1105 return elementData(lastRet = i);
1106 }
1107 }
1108
1109 public void remove() {
1110 if (lastRet == -1)
1111 throw new IllegalStateException();
1112 synchronized (Vector.this ) {
1113 checkForComodification();
1114 Vector.this .remove(lastRet);
1115 expectedModCount = modCount;
1116 }
1117 cursor = lastRet;
1118 lastRet = -1;
1119 }
1120
1121 final void checkForComodification() {
1122 if (modCount != expectedModCount)
1123 throw new ConcurrentModificationException();
1124 }
1125 }
1126
1127 /**
1128 * An optimized version of AbstractList.ListItr
1129 */
1130 final class ListItr extends Itr implements ListIterator<E> {
1131 ListItr(int index) {
1132 super ();
1133 cursor = index;
1134 }
1135
1136 public boolean hasPrevious() {
1137 return cursor != 0;
1138 }
1139
1140 public int nextIndex() {
1141 return cursor;
1142 }
1143
1144 public int previousIndex() {
1145 return cursor - 1;
1146 }
1147
1148 public E previous() {
1149 synchronized (Vector.this ) {
1150 checkForComodification();
1151 int i = cursor - 1;
1152 if (i < 0)
1153 throw new NoSuchElementException();
1154 cursor = i;
1155 return elementData(lastRet = i);
1156 }
1157 }
1158
1159 public void set(E e) {
1160 if (lastRet == -1)
1161 throw new IllegalStateException();
1162 synchronized (Vector.this ) {
1163 checkForComodification();
1164 Vector.this .set(lastRet, e);
1165 }
1166 }
1167
1168 public void add(E e) {
1169 int i = cursor;
1170 synchronized (Vector.this ) {
1171 checkForComodification();
1172 Vector.this .add(i, e);
1173 expectedModCount = modCount;
1174 }
1175 cursor = i + 1;
1176 lastRet = -1;
1177 }
1178 }
1179 }
|