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