• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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