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

# Content
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 }