ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk8/java/util/concurrent/CopyOnWriteArrayList.java
Revision: 1.1
Committed: Sat Mar 26 06:22:50 2016 UTC (8 years, 2 months ago) by jsr166
Branch: MAIN
Log Message:
fork jdk8 maintenance branch for source and jtreg tests

File Contents

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