1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * Written by Doug Lea with assistance from members of JCP JSR-166 27 * Expert Group. Adapted and released, under explicit permission, 28 * from JDK ArrayList.java which carries the following copyright: 29 * 30 * Copyright 1997 by Sun Microsystems, Inc., 31 * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. 32 * All rights reserved. 33 */ 34 35 package java.util.concurrent; 36 37 import java.lang.invoke.VarHandle; 38 import java.lang.reflect.Field; 39 import java.util.ArrayList; 40 import java.util.Arrays; 41 import java.util.Collection; 42 import java.util.Comparator; 43 import java.util.ConcurrentModificationException; 44 import java.util.Iterator; 45 import java.util.List; 46 import java.util.ListIterator; 47 import java.util.NoSuchElementException; 48 import java.util.Objects; 49 import java.util.RandomAccess; 50 import java.util.Spliterator; 51 import java.util.Spliterators; 52 import java.util.function.Consumer; 53 import java.util.function.Predicate; 54 import java.util.function.UnaryOperator; 55 import jdk.internal.misc.SharedSecrets; 56 57 // Android-changed: Removed javadoc link to collections framework docs 58 /** 59 * A thread-safe variant of {@link java.util.ArrayList} in which all mutative 60 * operations ({@code add}, {@code set}, and so on) are implemented by 61 * making a fresh copy of the underlying array. 62 * 63 * <p>This is ordinarily too costly, but may be <em>more</em> efficient 64 * than alternatives when traversal operations vastly outnumber 65 * mutations, and is useful when you cannot or don't want to 66 * synchronize traversals, yet need to preclude interference among 67 * concurrent threads. The "snapshot" style iterator method uses a 68 * reference to the state of the array at the point that the iterator 69 * was created. This array never changes during the lifetime of the 70 * iterator, so interference is impossible and the iterator is 71 * guaranteed not to throw {@code ConcurrentModificationException}. 72 * The iterator will not reflect additions, removals, or changes to 73 * the list since the iterator was created. Element-changing 74 * operations on iterators themselves ({@code remove}, {@code set}, and 75 * {@code add}) are not supported. These methods throw 76 * {@code UnsupportedOperationException}. 77 * 78 * <p>All elements are permitted, including {@code null}. 79 * 80 * <p>Memory consistency effects: As with other concurrent 81 * collections, actions in a thread prior to placing an object into a 82 * {@code CopyOnWriteArrayList} 83 * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> 84 * actions subsequent to the access or removal of that element from 85 * the {@code CopyOnWriteArrayList} in another thread. 86 * 87 * <p>This class is a member of the 88 * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework"> 89 * Java Collections Framework</a>. 90 * 91 * @since 1.5 92 * @author Doug Lea 93 * @param <E> the type of elements held in this list 94 */ 95 public class CopyOnWriteArrayList<E> 96 implements List<E>, RandomAccess, Cloneable, java.io.Serializable { 97 private static final long serialVersionUID = 8673264195747942595L; 98 99 /** 100 * The lock protecting all mutators. (We have a mild preference 101 * for builtin monitors over ReentrantLock when either will do.) 102 */ 103 final transient Object lock = new Object(); 104 105 /** The array, accessed only via getArray/setArray. */ 106 private transient volatile Object[] array; 107 108 /** 109 * Gets the array. Non-private so as to also be accessible 110 * from CopyOnWriteArraySet class. 111 */ getArray()112 final Object[] getArray() { 113 return array; 114 } 115 116 /** 117 * Sets the array. 118 */ setArray(Object[] a)119 final void setArray(Object[] a) { 120 array = a; 121 } 122 123 /** 124 * Creates an empty list. 125 */ CopyOnWriteArrayList()126 public CopyOnWriteArrayList() { 127 setArray(new Object[0]); 128 } 129 130 /** 131 * Creates a list containing the elements of the specified 132 * collection, in the order they are returned by the collection's 133 * iterator. 134 * 135 * @param c the collection of initially held elements 136 * @throws NullPointerException if the specified collection is null 137 */ CopyOnWriteArrayList(Collection<? extends E> c)138 public CopyOnWriteArrayList(Collection<? extends E> c) { 139 Object[] es; 140 if (c.getClass() == CopyOnWriteArrayList.class) 141 es = ((CopyOnWriteArrayList<?>)c).getArray(); 142 else { 143 es = c.toArray(); 144 // Android-changed: Defend against c.toArray (incorrectly) not returning Object[] 145 // (see b/204397945) 146 // if (c.getClass() != java.util.ArrayList.class) 147 if (es.getClass() != Object[].class) 148 es = Arrays.copyOf(es, es.length, Object[].class); 149 } 150 setArray(es); 151 } 152 153 /** 154 * Creates a list holding a copy of the given array. 155 * 156 * @param toCopyIn the array (a copy of this array is used as the 157 * internal array) 158 * @throws NullPointerException if the specified array is null 159 */ CopyOnWriteArrayList(E[] toCopyIn)160 public CopyOnWriteArrayList(E[] toCopyIn) { 161 setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class)); 162 } 163 164 /** 165 * Returns the number of elements in this list. 166 * 167 * @return the number of elements in this list 168 */ size()169 public int size() { 170 return getArray().length; 171 } 172 173 /** 174 * Returns {@code true} if this list contains no elements. 175 * 176 * @return {@code true} if this list contains no elements 177 */ isEmpty()178 public boolean isEmpty() { 179 return size() == 0; 180 } 181 182 /** 183 * static version of indexOf, to allow repeated calls without 184 * needing to re-acquire array each time. 185 * @param o element to search for 186 * @param es the array 187 * @param from first index to search 188 * @param to one past last index to search 189 * @return index of element, or -1 if absent 190 */ indexOfRange(Object o, Object[] es, int from, int to)191 private static int indexOfRange(Object o, Object[] es, int from, int to) { 192 if (o == null) { 193 for (int i = from; i < to; i++) 194 if (es[i] == null) 195 return i; 196 } else { 197 for (int i = from; i < to; i++) 198 if (o.equals(es[i])) 199 return i; 200 } 201 return -1; 202 } 203 204 /** 205 * static version of lastIndexOf. 206 * @param o element to search for 207 * @param es the array 208 * @param from index of first element of range, last element to search 209 * @param to one past last element of range, first element to search 210 * @return index of element, or -1 if absent 211 */ lastIndexOfRange(Object o, Object[] es, int from, int to)212 private static int lastIndexOfRange(Object o, Object[] es, int from, int to) { 213 if (o == null) { 214 for (int i = to - 1; i >= from; i--) 215 if (es[i] == null) 216 return i; 217 } else { 218 for (int i = to - 1; i >= from; i--) 219 if (o.equals(es[i])) 220 return i; 221 } 222 return -1; 223 } 224 225 /** 226 * Returns {@code true} if this list contains the specified element. 227 * More formally, returns {@code true} if and only if this list contains 228 * at least one element {@code e} such that {@code Objects.equals(o, e)}. 229 * 230 * @param o element whose presence in this list is to be tested 231 * @return {@code true} if this list contains the specified element 232 */ contains(Object o)233 public boolean contains(Object o) { 234 return indexOf(o) >= 0; 235 } 236 237 /** 238 * {@inheritDoc} 239 */ indexOf(Object o)240 public int indexOf(Object o) { 241 Object[] es = getArray(); 242 return indexOfRange(o, es, 0, es.length); 243 } 244 245 /** 246 * Returns the index of the first occurrence of the specified element in 247 * this list, searching forwards from {@code index}, or returns -1 if 248 * the element is not found. 249 * More formally, returns the lowest index {@code i} such that 250 * {@code i >= index && Objects.equals(get(i), e)}, 251 * or -1 if there is no such index. 252 * 253 * @param e element to search for 254 * @param index index to start searching from 255 * @return the index of the first occurrence of the element in 256 * this list at position {@code index} or later in the list; 257 * {@code -1} if the element is not found. 258 * @throws IndexOutOfBoundsException if the specified index is negative 259 */ indexOf(E e, int index)260 public int indexOf(E e, int index) { 261 Object[] es = getArray(); 262 return indexOfRange(e, es, index, es.length); 263 } 264 265 /** 266 * {@inheritDoc} 267 */ lastIndexOf(Object o)268 public int lastIndexOf(Object o) { 269 Object[] es = getArray(); 270 return lastIndexOfRange(o, es, 0, es.length); 271 } 272 273 /** 274 * Returns the index of the last occurrence of the specified element in 275 * this list, searching backwards from {@code index}, or returns -1 if 276 * the element is not found. 277 * More formally, returns the highest index {@code i} such that 278 * {@code i <= index && Objects.equals(get(i), e)}, 279 * or -1 if there is no such index. 280 * 281 * @param e element to search for 282 * @param index index to start searching backwards from 283 * @return the index of the last occurrence of the element at position 284 * less than or equal to {@code index} in this list; 285 * -1 if the element is not found. 286 * @throws IndexOutOfBoundsException if the specified index is greater 287 * than or equal to the current size of this list 288 */ lastIndexOf(E e, int index)289 public int lastIndexOf(E e, int index) { 290 Object[] es = getArray(); 291 return lastIndexOfRange(e, es, 0, index + 1); 292 } 293 294 /** 295 * Returns a shallow copy of this list. (The elements themselves 296 * are not copied.) 297 * 298 * @return a clone of this list 299 */ clone()300 public Object clone() { 301 try { 302 @SuppressWarnings("unchecked") 303 CopyOnWriteArrayList<E> clone = 304 (CopyOnWriteArrayList<E>) super.clone(); 305 clone.resetLock(); 306 // Unlike in readObject, here we cannot visibility-piggyback on the 307 // volatile write in setArray(). 308 VarHandle.releaseFence(); 309 return clone; 310 } catch (CloneNotSupportedException e) { 311 // this shouldn't happen, since we are Cloneable 312 throw new InternalError(); 313 } 314 } 315 316 /** 317 * Returns an array containing all of the elements in this list 318 * in proper sequence (from first to last element). 319 * 320 * <p>The returned array will be "safe" in that no references to it are 321 * maintained by this list. (In other words, this method must allocate 322 * a new array). The caller is thus free to modify the returned array. 323 * 324 * <p>This method acts as bridge between array-based and collection-based 325 * APIs. 326 * 327 * @return an array containing all the elements in this list 328 */ toArray()329 public Object[] toArray() { 330 return getArray().clone(); 331 } 332 333 /** 334 * Returns an array containing all of the elements in this list in 335 * proper sequence (from first to last element); the runtime type of 336 * the returned array is that of the specified array. If the list fits 337 * in the specified array, it is returned therein. Otherwise, a new 338 * array is allocated with the runtime type of the specified array and 339 * the size of this list. 340 * 341 * <p>If this list fits in the specified array with room to spare 342 * (i.e., the array has more elements than this list), the element in 343 * the array immediately following the end of the list is set to 344 * {@code null}. (This is useful in determining the length of this 345 * list <i>only</i> if the caller knows that this list does not contain 346 * any null elements.) 347 * 348 * <p>Like the {@link #toArray()} method, this method acts as bridge between 349 * array-based and collection-based APIs. Further, this method allows 350 * precise control over the runtime type of the output array, and may, 351 * under certain circumstances, be used to save allocation costs. 352 * 353 * <p>Suppose {@code x} is a list known to contain only strings. 354 * The following code can be used to dump the list into a newly 355 * allocated array of {@code String}: 356 * 357 * <pre> {@code String[] y = x.toArray(new String[0]);}</pre> 358 * 359 * Note that {@code toArray(new Object[0])} is identical in function to 360 * {@code toArray()}. 361 * 362 * @param a the array into which the elements of the list are to 363 * be stored, if it is big enough; otherwise, a new array of the 364 * same runtime type is allocated for this purpose. 365 * @return an array containing all the elements in this list 366 * @throws ArrayStoreException if the runtime type of the specified array 367 * is not a supertype of the runtime type of every element in 368 * this list 369 * @throws NullPointerException if the specified array is null 370 */ 371 @SuppressWarnings("unchecked") toArray(T[] a)372 public <T> T[] toArray(T[] a) { 373 Object[] es = getArray(); 374 int len = es.length; 375 if (a.length < len) 376 return (T[]) Arrays.copyOf(es, len, a.getClass()); 377 else { 378 System.arraycopy(es, 0, a, 0, len); 379 if (a.length > len) 380 a[len] = null; 381 return a; 382 } 383 } 384 385 // Positional Access Operations 386 387 @SuppressWarnings("unchecked") elementAt(Object[] a, int index)388 static <E> E elementAt(Object[] a, int index) { 389 return (E) a[index]; 390 } 391 outOfBounds(int index, int size)392 static String outOfBounds(int index, int size) { 393 return "Index: " + index + ", Size: " + size; 394 } 395 396 /** 397 * {@inheritDoc} 398 * 399 * @throws IndexOutOfBoundsException {@inheritDoc} 400 */ get(int index)401 public E get(int index) { 402 return elementAt(getArray(), index); 403 } 404 405 /** 406 * Replaces the element at the specified position in this list with the 407 * specified element. 408 * 409 * @throws IndexOutOfBoundsException {@inheritDoc} 410 */ set(int index, E element)411 public E set(int index, E element) { 412 synchronized (lock) { 413 Object[] es = getArray(); 414 E oldValue = elementAt(es, index); 415 416 if (oldValue != element) { 417 es = es.clone(); 418 es[index] = element; 419 } 420 // Ensure volatile write semantics even when oldvalue == element 421 setArray(es); 422 return oldValue; 423 } 424 } 425 426 /** 427 * Appends the specified element to the end of this list. 428 * 429 * @param e element to be appended to this list 430 * @return {@code true} (as specified by {@link Collection#add}) 431 */ add(E e)432 public boolean add(E e) { 433 synchronized (lock) { 434 Object[] es = getArray(); 435 int len = es.length; 436 es = Arrays.copyOf(es, len + 1); 437 es[len] = e; 438 setArray(es); 439 return true; 440 } 441 } 442 443 /** 444 * Inserts the specified element at the specified position in this 445 * list. Shifts the element currently at that position (if any) and 446 * any subsequent elements to the right (adds one to their indices). 447 * 448 * @throws IndexOutOfBoundsException {@inheritDoc} 449 */ add(int index, E element)450 public void add(int index, E element) { 451 synchronized (lock) { 452 Object[] es = getArray(); 453 int len = es.length; 454 if (index > len || index < 0) 455 throw new IndexOutOfBoundsException(outOfBounds(index, len)); 456 Object[] newElements; 457 int numMoved = len - index; 458 if (numMoved == 0) 459 newElements = Arrays.copyOf(es, len + 1); 460 else { 461 newElements = new Object[len + 1]; 462 System.arraycopy(es, 0, newElements, 0, index); 463 System.arraycopy(es, index, newElements, index + 1, 464 numMoved); 465 } 466 newElements[index] = element; 467 setArray(newElements); 468 } 469 } 470 471 /** 472 * Removes the element at the specified position in this list. 473 * Shifts any subsequent elements to the left (subtracts one from their 474 * indices). Returns the element that was removed from the list. 475 * 476 * @throws IndexOutOfBoundsException {@inheritDoc} 477 */ remove(int index)478 public E remove(int index) { 479 synchronized (lock) { 480 Object[] es = getArray(); 481 int len = es.length; 482 E oldValue = elementAt(es, index); 483 int numMoved = len - index - 1; 484 Object[] newElements; 485 if (numMoved == 0) 486 newElements = Arrays.copyOf(es, len - 1); 487 else { 488 newElements = new Object[len - 1]; 489 System.arraycopy(es, 0, newElements, 0, index); 490 System.arraycopy(es, index + 1, newElements, index, 491 numMoved); 492 } 493 setArray(newElements); 494 return oldValue; 495 } 496 } 497 498 /** 499 * Removes the first occurrence of the specified element from this list, 500 * if it is present. If this list does not contain the element, it is 501 * unchanged. More formally, removes the element with the lowest index 502 * {@code i} such that {@code Objects.equals(o, get(i))} 503 * (if such an element exists). Returns {@code true} if this list 504 * contained the specified element (or equivalently, if this list 505 * changed as a result of the call). 506 * 507 * @param o element to be removed from this list, if present 508 * @return {@code true} if this list contained the specified element 509 */ remove(Object o)510 public boolean remove(Object o) { 511 Object[] snapshot = getArray(); 512 int index = indexOfRange(o, snapshot, 0, snapshot.length); 513 return index >= 0 && remove(o, snapshot, index); 514 } 515 516 /** 517 * A version of remove(Object) using the strong hint that given 518 * recent snapshot contains o at the given index. 519 */ remove(Object o, Object[] snapshot, int index)520 private boolean remove(Object o, Object[] snapshot, int index) { 521 synchronized (lock) { 522 Object[] current = getArray(); 523 int len = current.length; 524 if (snapshot != current) findIndex: { 525 int prefix = Math.min(index, len); 526 for (int i = 0; i < prefix; i++) { 527 if (current[i] != snapshot[i] 528 && Objects.equals(o, current[i])) { 529 index = i; 530 break findIndex; 531 } 532 } 533 if (index >= len) 534 return false; 535 if (current[index] == o) 536 break findIndex; 537 index = indexOfRange(o, current, index, len); 538 if (index < 0) 539 return false; 540 } 541 Object[] newElements = new Object[len - 1]; 542 System.arraycopy(current, 0, newElements, 0, index); 543 System.arraycopy(current, index + 1, 544 newElements, index, 545 len - index - 1); 546 setArray(newElements); 547 return true; 548 } 549 } 550 551 /** 552 * Removes from this list all of the elements whose index is between 553 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. 554 * Shifts any succeeding elements to the left (reduces their index). 555 * This call shortens the list by {@code (toIndex - fromIndex)} elements. 556 * (If {@code toIndex==fromIndex}, this operation has no effect.) 557 * 558 * @param fromIndex index of first element to be removed 559 * @param toIndex index after last element to be removed 560 * @throws IndexOutOfBoundsException if fromIndex or toIndex out of range 561 * ({@code fromIndex < 0 || toIndex > size() || toIndex < fromIndex}) 562 */ removeRange(int fromIndex, int toIndex)563 void removeRange(int fromIndex, int toIndex) { 564 synchronized (lock) { 565 Object[] es = getArray(); 566 int len = es.length; 567 568 if (fromIndex < 0 || toIndex > len || toIndex < fromIndex) 569 throw new IndexOutOfBoundsException(); 570 int newlen = len - (toIndex - fromIndex); 571 int numMoved = len - toIndex; 572 if (numMoved == 0) 573 setArray(Arrays.copyOf(es, newlen)); 574 else { 575 Object[] newElements = new Object[newlen]; 576 System.arraycopy(es, 0, newElements, 0, fromIndex); 577 System.arraycopy(es, toIndex, newElements, 578 fromIndex, numMoved); 579 setArray(newElements); 580 } 581 } 582 } 583 584 /** 585 * Appends the element, if not present. 586 * 587 * @param e element to be added to this list, if absent 588 * @return {@code true} if the element was added 589 */ addIfAbsent(E e)590 public boolean addIfAbsent(E e) { 591 Object[] snapshot = getArray(); 592 return indexOfRange(e, snapshot, 0, snapshot.length) < 0 593 && addIfAbsent(e, snapshot); 594 } 595 596 /** 597 * A version of addIfAbsent using the strong hint that given 598 * recent snapshot does not contain e. 599 */ addIfAbsent(E e, Object[] snapshot)600 private boolean addIfAbsent(E e, Object[] snapshot) { 601 synchronized (lock) { 602 Object[] current = getArray(); 603 int len = current.length; 604 if (snapshot != current) { 605 // Optimize for lost race to another addXXX operation 606 int common = Math.min(snapshot.length, len); 607 for (int i = 0; i < common; i++) 608 if (current[i] != snapshot[i] 609 && Objects.equals(e, current[i])) 610 return false; 611 if (indexOfRange(e, current, common, len) >= 0) 612 return false; 613 } 614 Object[] newElements = Arrays.copyOf(current, len + 1); 615 newElements[len] = e; 616 setArray(newElements); 617 return true; 618 } 619 } 620 621 /** 622 * Returns {@code true} if this list contains all of the elements of the 623 * specified collection. 624 * 625 * @param c collection to be checked for containment in this list 626 * @return {@code true} if this list contains all of the elements of the 627 * specified collection 628 * @throws NullPointerException if the specified collection is null 629 * @see #contains(Object) 630 */ containsAll(Collection<?> c)631 public boolean containsAll(Collection<?> c) { 632 Object[] es = getArray(); 633 int len = es.length; 634 for (Object e : c) { 635 if (indexOfRange(e, es, 0, len) < 0) 636 return false; 637 } 638 return true; 639 } 640 641 /** 642 * Removes from this list all of its elements that are contained in 643 * the specified collection. This is a particularly expensive operation 644 * in this class because of the need for an internal temporary array. 645 * 646 * @param c collection containing elements to be removed from this list 647 * @return {@code true} if this list changed as a result of the call 648 * @throws ClassCastException if the class of an element of this list 649 * is incompatible with the specified collection 650 * (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>) 651 * @throws NullPointerException if this list contains a null element and the 652 * specified collection does not permit null elements 653 * (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>), 654 * or if the specified collection is null 655 * @see #remove(Object) 656 */ removeAll(Collection<?> c)657 public boolean removeAll(Collection<?> c) { 658 Objects.requireNonNull(c); 659 return bulkRemove(e -> c.contains(e)); 660 } 661 662 /** 663 * Retains only the elements in this list that are contained in the 664 * specified collection. In other words, removes from this list all of 665 * its elements that are not contained in the specified collection. 666 * 667 * @param c collection containing elements to be retained in this list 668 * @return {@code true} if this list changed as a result of the call 669 * @throws ClassCastException if the class of an element of this list 670 * is incompatible with the specified collection 671 * (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>) 672 * @throws NullPointerException if this list contains a null element and the 673 * specified collection does not permit null elements 674 * (<a href="{@docRoot}/java.base/java/util/Collection.html#optional-restrictions">optional</a>), 675 * or if the specified collection is null 676 * @see #remove(Object) 677 */ retainAll(Collection<?> c)678 public boolean retainAll(Collection<?> c) { 679 Objects.requireNonNull(c); 680 return bulkRemove(e -> !c.contains(e)); 681 } 682 683 /** 684 * Appends all of the elements in the specified collection that 685 * are not already contained in this list, to the end of 686 * this list, in the order that they are returned by the 687 * specified collection's iterator. 688 * 689 * @param c collection containing elements to be added to this list 690 * @return the number of elements added 691 * @throws NullPointerException if the specified collection is null 692 * @see #addIfAbsent(Object) 693 */ addAllAbsent(Collection<? extends E> c)694 public int addAllAbsent(Collection<? extends E> c) { 695 Object[] cs = c.toArray(); 696 if (c.getClass() != ArrayList.class) { 697 cs = cs.clone(); 698 } 699 if (cs.length == 0) 700 return 0; 701 synchronized (lock) { 702 Object[] es = getArray(); 703 int len = es.length; 704 int added = 0; 705 // uniquify and compact elements in cs 706 for (int i = 0; i < cs.length; ++i) { 707 Object e = cs[i]; 708 if (indexOfRange(e, es, 0, len) < 0 && 709 indexOfRange(e, cs, 0, added) < 0) 710 cs[added++] = e; 711 } 712 if (added > 0) { 713 Object[] newElements = Arrays.copyOf(es, len + added); 714 System.arraycopy(cs, 0, newElements, len, added); 715 setArray(newElements); 716 } 717 return added; 718 } 719 } 720 721 /** 722 * Removes all of the elements from this list. 723 * The list will be empty after this call returns. 724 */ clear()725 public void clear() { 726 synchronized (lock) { 727 setArray(new Object[0]); 728 } 729 } 730 731 /** 732 * Appends all of the elements in the specified collection to the end 733 * of this list, in the order that they are returned by the specified 734 * collection's iterator. 735 * 736 * @param c collection containing elements to be added to this list 737 * @return {@code true} if this list changed as a result of the call 738 * @throws NullPointerException if the specified collection is null 739 * @see #add(Object) 740 */ addAll(Collection<? extends E> c)741 public boolean addAll(Collection<? extends E> c) { 742 Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ? 743 ((CopyOnWriteArrayList<?>)c).getArray() : c.toArray(); 744 if (cs.length == 0) 745 return false; 746 synchronized (lock) { 747 Object[] es = getArray(); 748 int len = es.length; 749 Object[] newElements; 750 if (len == 0 && (c.getClass() == CopyOnWriteArrayList.class || 751 c.getClass() == ArrayList.class)) { 752 newElements = cs; 753 } else { 754 newElements = Arrays.copyOf(es, len + cs.length); 755 System.arraycopy(cs, 0, newElements, len, cs.length); 756 } 757 setArray(newElements); 758 return true; 759 } 760 } 761 762 /** 763 * Inserts all of the elements in the specified collection into this 764 * list, starting at the specified position. Shifts the element 765 * currently at that position (if any) and any subsequent elements to 766 * the right (increases their indices). The new elements will appear 767 * in this list in the order that they are returned by the 768 * specified collection's iterator. 769 * 770 * @param index index at which to insert the first element 771 * from the specified collection 772 * @param c collection containing elements to be added to this list 773 * @return {@code true} if this list changed as a result of the call 774 * @throws IndexOutOfBoundsException {@inheritDoc} 775 * @throws NullPointerException if the specified collection is null 776 * @see #add(int,Object) 777 */ addAll(int index, Collection<? extends E> c)778 public boolean addAll(int index, Collection<? extends E> c) { 779 Object[] cs = c.toArray(); 780 synchronized (lock) { 781 Object[] es = getArray(); 782 int len = es.length; 783 if (index > len || index < 0) 784 throw new IndexOutOfBoundsException(outOfBounds(index, len)); 785 if (cs.length == 0) 786 return false; 787 int numMoved = len - index; 788 Object[] newElements; 789 if (numMoved == 0) 790 newElements = Arrays.copyOf(es, len + cs.length); 791 else { 792 newElements = new Object[len + cs.length]; 793 System.arraycopy(es, 0, newElements, 0, index); 794 System.arraycopy(es, index, 795 newElements, index + cs.length, 796 numMoved); 797 } 798 System.arraycopy(cs, 0, newElements, index, cs.length); 799 setArray(newElements); 800 return true; 801 } 802 } 803 804 /** 805 * @throws NullPointerException {@inheritDoc} 806 */ forEach(Consumer<? super E> action)807 public void forEach(Consumer<? super E> action) { 808 Objects.requireNonNull(action); 809 for (Object x : getArray()) { 810 @SuppressWarnings("unchecked") E e = (E) x; 811 action.accept(e); 812 } 813 } 814 815 /** 816 * @throws NullPointerException {@inheritDoc} 817 */ removeIf(Predicate<? super E> filter)818 public boolean removeIf(Predicate<? super E> filter) { 819 Objects.requireNonNull(filter); 820 return bulkRemove(filter); 821 } 822 823 // A tiny bit set implementation 824 nBits(int n)825 private static long[] nBits(int n) { 826 return new long[((n - 1) >> 6) + 1]; 827 } setBit(long[] bits, int i)828 private static void setBit(long[] bits, int i) { 829 bits[i >> 6] |= 1L << i; 830 } isClear(long[] bits, int i)831 private static boolean isClear(long[] bits, int i) { 832 return (bits[i >> 6] & (1L << i)) == 0; 833 } 834 bulkRemove(Predicate<? super E> filter)835 private boolean bulkRemove(Predicate<? super E> filter) { 836 synchronized (lock) { 837 return bulkRemove(filter, 0, getArray().length); 838 } 839 } 840 bulkRemove(Predicate<? super E> filter, int i, int end)841 boolean bulkRemove(Predicate<? super E> filter, int i, int end) { 842 // assert Thread.holdsLock(lock); 843 final Object[] es = getArray(); 844 // Optimize for initial run of survivors 845 for (; i < end && !filter.test(elementAt(es, i)); i++) 846 ; 847 if (i < end) { 848 final int beg = i; 849 final long[] deathRow = nBits(end - beg); 850 int deleted = 1; 851 deathRow[0] = 1L; // set bit 0 852 for (i = beg + 1; i < end; i++) 853 if (filter.test(elementAt(es, i))) { 854 setBit(deathRow, i - beg); 855 deleted++; 856 } 857 // Did filter reentrantly modify the list? 858 if (es != getArray()) 859 throw new ConcurrentModificationException(); 860 final Object[] newElts = Arrays.copyOf(es, es.length - deleted); 861 int w = beg; 862 for (i = beg; i < end; i++) 863 if (isClear(deathRow, i - beg)) 864 newElts[w++] = es[i]; 865 System.arraycopy(es, i, newElts, w, es.length - i); 866 setArray(newElts); 867 return true; 868 } else { 869 if (es != getArray()) 870 throw new ConcurrentModificationException(); 871 return false; 872 } 873 } 874 replaceAll(UnaryOperator<E> operator)875 public void replaceAll(UnaryOperator<E> operator) { 876 synchronized (lock) { 877 replaceAllRange(operator, 0, getArray().length); 878 } 879 } 880 replaceAllRange(UnaryOperator<E> operator, int i, int end)881 void replaceAllRange(UnaryOperator<E> operator, int i, int end) { 882 // assert Thread.holdsLock(lock); 883 Objects.requireNonNull(operator); 884 final Object[] es = getArray().clone(); 885 for (; i < end; i++) 886 es[i] = operator.apply(elementAt(es, i)); 887 setArray(es); 888 } 889 sort(Comparator<? super E> c)890 public void sort(Comparator<? super E> c) { 891 synchronized (lock) { 892 sortRange(c, 0, getArray().length); 893 } 894 } 895 896 @SuppressWarnings("unchecked") sortRange(Comparator<? super E> c, int i, int end)897 void sortRange(Comparator<? super E> c, int i, int end) { 898 // assert Thread.holdsLock(lock); 899 final Object[] es = getArray().clone(); 900 Arrays.sort(es, i, end, (Comparator<Object>)c); 901 setArray(es); 902 } 903 904 /** 905 * Saves this list to a stream (that is, serializes it). 906 * 907 * @param s the stream 908 * @throws java.io.IOException if an I/O error occurs 909 * @serialData The length of the array backing the list is emitted 910 * (int), followed by all of its elements (each an Object) 911 * in the proper order. 912 */ writeObject(java.io.ObjectOutputStream s)913 private void writeObject(java.io.ObjectOutputStream s) 914 throws java.io.IOException { 915 916 s.defaultWriteObject(); 917 918 Object[] es = getArray(); 919 // Write out array length 920 s.writeInt(es.length); 921 922 // Write out all elements in the proper order. 923 for (Object element : es) 924 s.writeObject(element); 925 } 926 927 /** 928 * Reconstitutes this list from a stream (that is, deserializes it). 929 * @param s the stream 930 * @throws ClassNotFoundException if the class of a serialized object 931 * could not be found 932 * @throws java.io.IOException if an I/O error occurs 933 */ readObject(java.io.ObjectInputStream s)934 private void readObject(java.io.ObjectInputStream s) 935 throws java.io.IOException, ClassNotFoundException { 936 937 s.defaultReadObject(); 938 939 // bind to new lock 940 resetLock(); 941 942 // Read in array length and allocate array 943 int len = s.readInt(); 944 SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, len); 945 Object[] es = new Object[len]; 946 947 // Read in all elements in the proper order. 948 for (int i = 0; i < len; i++) 949 es[i] = s.readObject(); 950 setArray(es); 951 } 952 953 /** 954 * Returns a string representation of this list. The string 955 * representation consists of the string representations of the list's 956 * elements in the order they are returned by its iterator, enclosed in 957 * square brackets ({@code "[]"}). Adjacent elements are separated by 958 * the characters {@code ", "} (comma and space). Elements are 959 * converted to strings as by {@link String#valueOf(Object)}. 960 * 961 * @return a string representation of this list 962 */ toString()963 public String toString() { 964 return Arrays.toString(getArray()); 965 } 966 967 /** 968 * Compares the specified object with this list for equality. 969 * Returns {@code true} if the specified object is the same object 970 * as this object, or if it is also a {@link List} and the sequence 971 * of elements returned by an {@linkplain List#iterator() iterator} 972 * over the specified list is the same as the sequence returned by 973 * an iterator over this list. The two sequences are considered to 974 * be the same if they have the same length and corresponding 975 * elements at the same position in the sequence are <em>equal</em>. 976 * Two elements {@code e1} and {@code e2} are considered 977 * <em>equal</em> if {@code Objects.equals(e1, e2)}. 978 * 979 * @param o the object to be compared for equality with this list 980 * @return {@code true} if the specified object is equal to this list 981 */ equals(Object o)982 public boolean equals(Object o) { 983 if (o == this) 984 return true; 985 if (!(o instanceof List)) 986 return false; 987 988 List<?> list = (List<?>)o; 989 Iterator<?> it = list.iterator(); 990 for (Object element : getArray()) 991 if (!it.hasNext() || !Objects.equals(element, it.next())) 992 return false; 993 return !it.hasNext(); 994 } 995 hashCodeOfRange(Object[] es, int from, int to)996 private static int hashCodeOfRange(Object[] es, int from, int to) { 997 int hashCode = 1; 998 for (int i = from; i < to; i++) { 999 Object x = es[i]; 1000 hashCode = 31 * hashCode + (x == null ? 0 : x.hashCode()); 1001 } 1002 return hashCode; 1003 } 1004 1005 /** 1006 * Returns the hash code value for this list. 1007 * 1008 * <p>This implementation uses the definition in {@link List#hashCode}. 1009 * 1010 * @return the hash code value for this list 1011 */ hashCode()1012 public int hashCode() { 1013 Object[] es = getArray(); 1014 return hashCodeOfRange(es, 0, es.length); 1015 } 1016 1017 /** 1018 * Returns an iterator over the elements in this list in proper sequence. 1019 * 1020 * <p>The returned iterator provides a snapshot of the state of the list 1021 * when the iterator was constructed. No synchronization is needed while 1022 * traversing the iterator. The iterator does <em>NOT</em> support the 1023 * {@code remove} method. 1024 * 1025 * @return an iterator over the elements in this list in proper sequence 1026 */ iterator()1027 public Iterator<E> iterator() { 1028 return new COWIterator<E>(getArray(), 0); 1029 } 1030 1031 /** 1032 * {@inheritDoc} 1033 * 1034 * <p>The returned iterator provides a snapshot of the state of the list 1035 * when the iterator was constructed. No synchronization is needed while 1036 * traversing the iterator. The iterator does <em>NOT</em> support the 1037 * {@code remove}, {@code set} or {@code add} methods. 1038 */ listIterator()1039 public ListIterator<E> listIterator() { 1040 return new COWIterator<E>(getArray(), 0); 1041 } 1042 1043 /** 1044 * {@inheritDoc} 1045 * 1046 * <p>The returned iterator provides a snapshot of the state of the list 1047 * when the iterator was constructed. No synchronization is needed while 1048 * traversing the iterator. The iterator does <em>NOT</em> support the 1049 * {@code remove}, {@code set} or {@code add} methods. 1050 * 1051 * @throws IndexOutOfBoundsException {@inheritDoc} 1052 */ listIterator(int index)1053 public ListIterator<E> listIterator(int index) { 1054 Object[] es = getArray(); 1055 int len = es.length; 1056 if (index < 0 || index > len) 1057 throw new IndexOutOfBoundsException(outOfBounds(index, len)); 1058 1059 return new COWIterator<E>(es, index); 1060 } 1061 1062 /** 1063 * Returns a {@link Spliterator} over the elements in this list. 1064 * 1065 * <p>The {@code Spliterator} reports {@link Spliterator#IMMUTABLE}, 1066 * {@link Spliterator#ORDERED}, {@link Spliterator#SIZED}, and 1067 * {@link Spliterator#SUBSIZED}. 1068 * 1069 * <p>The spliterator provides a snapshot of the state of the list 1070 * when the spliterator was constructed. No synchronization is needed while 1071 * operating on the spliterator. 1072 * 1073 * @return a {@code Spliterator} over the elements in this list 1074 * @since 1.8 1075 */ spliterator()1076 public Spliterator<E> spliterator() { 1077 return Spliterators.spliterator 1078 (getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED); 1079 } 1080 1081 static final class COWIterator<E> implements ListIterator<E> { 1082 /** Snapshot of the array */ 1083 private final Object[] snapshot; 1084 /** Index of element to be returned by subsequent call to next. */ 1085 private int cursor; 1086 COWIterator(Object[] es, int initialCursor)1087 COWIterator(Object[] es, int initialCursor) { 1088 cursor = initialCursor; 1089 snapshot = es; 1090 } 1091 hasNext()1092 public boolean hasNext() { 1093 return cursor < snapshot.length; 1094 } 1095 hasPrevious()1096 public boolean hasPrevious() { 1097 return cursor > 0; 1098 } 1099 1100 @SuppressWarnings("unchecked") next()1101 public E next() { 1102 if (! hasNext()) 1103 throw new NoSuchElementException(); 1104 return (E) snapshot[cursor++]; 1105 } 1106 1107 @SuppressWarnings("unchecked") previous()1108 public E previous() { 1109 if (! hasPrevious()) 1110 throw new NoSuchElementException(); 1111 return (E) snapshot[--cursor]; 1112 } 1113 nextIndex()1114 public int nextIndex() { 1115 return cursor; 1116 } 1117 previousIndex()1118 public int previousIndex() { 1119 return cursor - 1; 1120 } 1121 1122 /** 1123 * Not supported. Always throws UnsupportedOperationException. 1124 * @throws UnsupportedOperationException always; {@code remove} 1125 * is not supported by this iterator. 1126 */ remove()1127 public void remove() { 1128 throw new UnsupportedOperationException(); 1129 } 1130 1131 /** 1132 * Not supported. Always throws UnsupportedOperationException. 1133 * @throws UnsupportedOperationException always; {@code set} 1134 * is not supported by this iterator. 1135 */ set(E e)1136 public void set(E e) { 1137 throw new UnsupportedOperationException(); 1138 } 1139 1140 /** 1141 * Not supported. Always throws UnsupportedOperationException. 1142 * @throws UnsupportedOperationException always; {@code add} 1143 * is not supported by this iterator. 1144 */ add(E e)1145 public void add(E e) { 1146 throw new UnsupportedOperationException(); 1147 } 1148 1149 @Override forEachRemaining(Consumer<? super E> action)1150 public void forEachRemaining(Consumer<? super E> action) { 1151 Objects.requireNonNull(action); 1152 final int size = snapshot.length; 1153 int i = cursor; 1154 cursor = size; 1155 for (; i < size; i++) 1156 action.accept(elementAt(snapshot, i)); 1157 } 1158 } 1159 1160 /** 1161 * Returns a view of the portion of this list between 1162 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. 1163 * The returned list is backed by this list, so changes in the 1164 * returned list are reflected in this list. 1165 * 1166 * <p>The semantics of the list returned by this method become 1167 * undefined if the backing list (i.e., this list) is modified in 1168 * any way other than via the returned list. 1169 * 1170 * @param fromIndex low endpoint (inclusive) of the subList 1171 * @param toIndex high endpoint (exclusive) of the subList 1172 * @return a view of the specified range within this list 1173 * @throws IndexOutOfBoundsException {@inheritDoc} 1174 */ subList(int fromIndex, int toIndex)1175 public List<E> subList(int fromIndex, int toIndex) { 1176 synchronized (lock) { 1177 Object[] es = getArray(); 1178 int len = es.length; 1179 int size = toIndex - fromIndex; 1180 if (fromIndex < 0 || toIndex > len || size < 0) 1181 throw new IndexOutOfBoundsException(); 1182 return new COWSubList(es, fromIndex, size); 1183 } 1184 } 1185 1186 /** 1187 * Sublist for CopyOnWriteArrayList. 1188 */ 1189 private class COWSubList implements List<E>, RandomAccess { 1190 private final int offset; 1191 private int size; 1192 private Object[] expectedArray; 1193 COWSubList(Object[] es, int offset, int size)1194 COWSubList(Object[] es, int offset, int size) { 1195 // assert Thread.holdsLock(lock); 1196 expectedArray = es; 1197 this.offset = offset; 1198 this.size = size; 1199 } 1200 checkForComodification()1201 private void checkForComodification() { 1202 // assert Thread.holdsLock(lock); 1203 if (getArray() != expectedArray) 1204 throw new ConcurrentModificationException(); 1205 } 1206 getArrayChecked()1207 private Object[] getArrayChecked() { 1208 // assert Thread.holdsLock(lock); 1209 Object[] a = getArray(); 1210 if (a != expectedArray) 1211 throw new ConcurrentModificationException(); 1212 return a; 1213 } 1214 rangeCheck(int index)1215 private void rangeCheck(int index) { 1216 // assert Thread.holdsLock(lock); 1217 if (index < 0 || index >= size) 1218 throw new IndexOutOfBoundsException(outOfBounds(index, size)); 1219 } 1220 rangeCheckForAdd(int index)1221 private void rangeCheckForAdd(int index) { 1222 // assert Thread.holdsLock(lock); 1223 if (index < 0 || index > size) 1224 throw new IndexOutOfBoundsException(outOfBounds(index, size)); 1225 } 1226 toArray()1227 public Object[] toArray() { 1228 final Object[] es; 1229 final int offset; 1230 final int size; 1231 synchronized (lock) { 1232 es = getArrayChecked(); 1233 offset = this.offset; 1234 size = this.size; 1235 } 1236 return Arrays.copyOfRange(es, offset, offset + size); 1237 } 1238 1239 @SuppressWarnings("unchecked") toArray(T[] a)1240 public <T> T[] toArray(T[] a) { 1241 final Object[] es; 1242 final int offset; 1243 final int size; 1244 synchronized (lock) { 1245 es = getArrayChecked(); 1246 offset = this.offset; 1247 size = this.size; 1248 } 1249 if (a.length < size) 1250 return (T[]) Arrays.copyOfRange( 1251 es, offset, offset + size, a.getClass()); 1252 else { 1253 System.arraycopy(es, offset, a, 0, size); 1254 if (a.length > size) 1255 a[size] = null; 1256 return a; 1257 } 1258 } 1259 indexOf(Object o)1260 public int indexOf(Object o) { 1261 final Object[] es; 1262 final int offset; 1263 final int size; 1264 synchronized (lock) { 1265 es = getArrayChecked(); 1266 offset = this.offset; 1267 size = this.size; 1268 } 1269 int i = indexOfRange(o, es, offset, offset + size); 1270 return (i == -1) ? -1 : i - offset; 1271 } 1272 lastIndexOf(Object o)1273 public int lastIndexOf(Object o) { 1274 final Object[] es; 1275 final int offset; 1276 final int size; 1277 synchronized (lock) { 1278 es = getArrayChecked(); 1279 offset = this.offset; 1280 size = this.size; 1281 } 1282 int i = lastIndexOfRange(o, es, offset, offset + size); 1283 return (i == -1) ? -1 : i - offset; 1284 } 1285 contains(Object o)1286 public boolean contains(Object o) { 1287 return indexOf(o) >= 0; 1288 } 1289 containsAll(Collection<?> c)1290 public boolean containsAll(Collection<?> c) { 1291 final Object[] es; 1292 final int offset; 1293 final int size; 1294 synchronized (lock) { 1295 es = getArrayChecked(); 1296 offset = this.offset; 1297 size = this.size; 1298 } 1299 for (Object o : c) 1300 if (indexOfRange(o, es, offset, offset + size) < 0) 1301 return false; 1302 return true; 1303 } 1304 isEmpty()1305 public boolean isEmpty() { 1306 return size() == 0; 1307 } 1308 toString()1309 public String toString() { 1310 return Arrays.toString(toArray()); 1311 } 1312 hashCode()1313 public int hashCode() { 1314 final Object[] es; 1315 final int offset; 1316 final int size; 1317 synchronized (lock) { 1318 es = getArrayChecked(); 1319 offset = this.offset; 1320 size = this.size; 1321 } 1322 return hashCodeOfRange(es, offset, offset + size); 1323 } 1324 equals(Object o)1325 public boolean equals(Object o) { 1326 if (o == this) 1327 return true; 1328 if (!(o instanceof List)) 1329 return false; 1330 Iterator<?> it = ((List<?>)o).iterator(); 1331 1332 final Object[] es; 1333 final int offset; 1334 final int size; 1335 synchronized (lock) { 1336 es = getArrayChecked(); 1337 offset = this.offset; 1338 size = this.size; 1339 } 1340 1341 for (int i = offset, end = offset + size; i < end; i++) 1342 if (!it.hasNext() || !Objects.equals(es[i], it.next())) 1343 return false; 1344 return !it.hasNext(); 1345 } 1346 set(int index, E element)1347 public E set(int index, E element) { 1348 synchronized (lock) { 1349 rangeCheck(index); 1350 checkForComodification(); 1351 E x = CopyOnWriteArrayList.this.set(offset + index, element); 1352 expectedArray = getArray(); 1353 return x; 1354 } 1355 } 1356 get(int index)1357 public E get(int index) { 1358 synchronized (lock) { 1359 rangeCheck(index); 1360 checkForComodification(); 1361 return CopyOnWriteArrayList.this.get(offset + index); 1362 } 1363 } 1364 size()1365 public int size() { 1366 synchronized (lock) { 1367 checkForComodification(); 1368 return size; 1369 } 1370 } 1371 add(E element)1372 public boolean add(E element) { 1373 synchronized (lock) { 1374 checkForComodification(); 1375 CopyOnWriteArrayList.this.add(offset + size, element); 1376 expectedArray = getArray(); 1377 size++; 1378 } 1379 return true; 1380 } 1381 add(int index, E element)1382 public void add(int index, E element) { 1383 synchronized (lock) { 1384 checkForComodification(); 1385 rangeCheckForAdd(index); 1386 CopyOnWriteArrayList.this.add(offset + index, element); 1387 expectedArray = getArray(); 1388 size++; 1389 } 1390 } 1391 addAll(Collection<? extends E> c)1392 public boolean addAll(Collection<? extends E> c) { 1393 synchronized (lock) { 1394 final Object[] oldArray = getArrayChecked(); 1395 boolean modified = 1396 CopyOnWriteArrayList.this.addAll(offset + size, c); 1397 size += (expectedArray = getArray()).length - oldArray.length; 1398 return modified; 1399 } 1400 } 1401 addAll(int index, Collection<? extends E> c)1402 public boolean addAll(int index, Collection<? extends E> c) { 1403 synchronized (lock) { 1404 rangeCheckForAdd(index); 1405 final Object[] oldArray = getArrayChecked(); 1406 boolean modified = 1407 CopyOnWriteArrayList.this.addAll(offset + index, c); 1408 size += (expectedArray = getArray()).length - oldArray.length; 1409 return modified; 1410 } 1411 } 1412 clear()1413 public void clear() { 1414 synchronized (lock) { 1415 checkForComodification(); 1416 removeRange(offset, offset + size); 1417 expectedArray = getArray(); 1418 size = 0; 1419 } 1420 } 1421 remove(int index)1422 public E remove(int index) { 1423 synchronized (lock) { 1424 rangeCheck(index); 1425 checkForComodification(); 1426 E result = CopyOnWriteArrayList.this.remove(offset + index); 1427 expectedArray = getArray(); 1428 size--; 1429 return result; 1430 } 1431 } 1432 remove(Object o)1433 public boolean remove(Object o) { 1434 synchronized (lock) { 1435 checkForComodification(); 1436 int index = indexOf(o); 1437 if (index == -1) 1438 return false; 1439 remove(index); 1440 return true; 1441 } 1442 } 1443 iterator()1444 public Iterator<E> iterator() { 1445 return listIterator(0); 1446 } 1447 listIterator()1448 public ListIterator<E> listIterator() { 1449 return listIterator(0); 1450 } 1451 listIterator(int index)1452 public ListIterator<E> listIterator(int index) { 1453 synchronized (lock) { 1454 checkForComodification(); 1455 rangeCheckForAdd(index); 1456 return new COWSubListIterator<E>( 1457 CopyOnWriteArrayList.this, index, offset, size); 1458 } 1459 } 1460 subList(int fromIndex, int toIndex)1461 public List<E> subList(int fromIndex, int toIndex) { 1462 synchronized (lock) { 1463 checkForComodification(); 1464 if (fromIndex < 0 || toIndex > size || fromIndex > toIndex) 1465 throw new IndexOutOfBoundsException(); 1466 return new COWSubList(expectedArray, fromIndex + offset, toIndex - fromIndex); 1467 } 1468 } 1469 forEach(Consumer<? super E> action)1470 public void forEach(Consumer<? super E> action) { 1471 Objects.requireNonNull(action); 1472 int i, end; final Object[] es; 1473 synchronized (lock) { 1474 es = getArrayChecked(); 1475 i = offset; 1476 end = i + size; 1477 } 1478 for (; i < end; i++) 1479 action.accept(elementAt(es, i)); 1480 } 1481 replaceAll(UnaryOperator<E> operator)1482 public void replaceAll(UnaryOperator<E> operator) { 1483 synchronized (lock) { 1484 checkForComodification(); 1485 replaceAllRange(operator, offset, offset + size); 1486 expectedArray = getArray(); 1487 } 1488 } 1489 sort(Comparator<? super E> c)1490 public void sort(Comparator<? super E> c) { 1491 synchronized (lock) { 1492 checkForComodification(); 1493 sortRange(c, offset, offset + size); 1494 expectedArray = getArray(); 1495 } 1496 } 1497 removeAll(Collection<?> c)1498 public boolean removeAll(Collection<?> c) { 1499 Objects.requireNonNull(c); 1500 return bulkRemove(e -> c.contains(e)); 1501 } 1502 retainAll(Collection<?> c)1503 public boolean retainAll(Collection<?> c) { 1504 Objects.requireNonNull(c); 1505 return bulkRemove(e -> !c.contains(e)); 1506 } 1507 removeIf(Predicate<? super E> filter)1508 public boolean removeIf(Predicate<? super E> filter) { 1509 Objects.requireNonNull(filter); 1510 return bulkRemove(filter); 1511 } 1512 bulkRemove(Predicate<? super E> filter)1513 private boolean bulkRemove(Predicate<? super E> filter) { 1514 synchronized (lock) { 1515 final Object[] oldArray = getArrayChecked(); 1516 boolean modified = CopyOnWriteArrayList.this.bulkRemove( 1517 filter, offset, offset + size); 1518 size += (expectedArray = getArray()).length - oldArray.length; 1519 return modified; 1520 } 1521 } 1522 spliterator()1523 public Spliterator<E> spliterator() { 1524 synchronized (lock) { 1525 return Spliterators.spliterator( 1526 getArrayChecked(), offset, offset + size, 1527 Spliterator.IMMUTABLE | Spliterator.ORDERED); 1528 } 1529 } 1530 1531 } 1532 1533 private static class COWSubListIterator<E> implements ListIterator<E> { 1534 private final ListIterator<E> it; 1535 private final int offset; 1536 private final int size; 1537 COWSubListIterator(List<E> l, int index, int offset, int size)1538 COWSubListIterator(List<E> l, int index, int offset, int size) { 1539 this.offset = offset; 1540 this.size = size; 1541 it = l.listIterator(index + offset); 1542 } 1543 hasNext()1544 public boolean hasNext() { 1545 return nextIndex() < size; 1546 } 1547 next()1548 public E next() { 1549 if (hasNext()) 1550 return it.next(); 1551 else 1552 throw new NoSuchElementException(); 1553 } 1554 hasPrevious()1555 public boolean hasPrevious() { 1556 return previousIndex() >= 0; 1557 } 1558 previous()1559 public E previous() { 1560 if (hasPrevious()) 1561 return it.previous(); 1562 else 1563 throw new NoSuchElementException(); 1564 } 1565 nextIndex()1566 public int nextIndex() { 1567 return it.nextIndex() - offset; 1568 } 1569 previousIndex()1570 public int previousIndex() { 1571 return it.previousIndex() - offset; 1572 } 1573 remove()1574 public void remove() { 1575 throw new UnsupportedOperationException(); 1576 } 1577 set(E e)1578 public void set(E e) { 1579 throw new UnsupportedOperationException(); 1580 } 1581 add(E e)1582 public void add(E e) { 1583 throw new UnsupportedOperationException(); 1584 } 1585 1586 @Override 1587 @SuppressWarnings("unchecked") forEachRemaining(Consumer<? super E> action)1588 public void forEachRemaining(Consumer<? super E> action) { 1589 Objects.requireNonNull(action); 1590 while (hasNext()) { 1591 action.accept(it.next()); 1592 } 1593 } 1594 } 1595 1596 /** Initializes the lock; for use when deserializing or cloning. */ resetLock()1597 private void resetLock() { 1598 Field lockField = java.security.AccessController.doPrivileged( 1599 (java.security.PrivilegedAction<Field>) () -> { 1600 try { 1601 Field f = CopyOnWriteArrayList.class 1602 .getDeclaredField("lock"); 1603 f.setAccessible(true); 1604 return f; 1605 } catch (ReflectiveOperationException e) { 1606 throw new Error(e); 1607 }}); 1608 try { 1609 lockField.set(this, new Object()); 1610 } catch (IllegalAccessException e) { 1611 throw new Error(e); 1612 } 1613 } 1614 } 1615