ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/CopyOnWriteArrayList.java
Revision: 1.127
Committed: Tue Feb 17 18:55:39 2015 UTC (9 years, 3 months ago) by jsr166
Branch: MAIN
Changes since 1.126: +1 -1 lines
Log Message:
standardize code sample idiom: * <pre> {@code

File Contents

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