ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/CopyOnWriteArrayList.java
Revision: 1.124
Committed: Sun Jan 25 20:07:01 2015 UTC (9 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.123: +40 -159 lines
Log Message:
prefer builtin monitor to ReentrantLock when either will do

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