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