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