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