ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/CopyOnWriteArrayList.java
Revision: 1.100
Committed: Wed Mar 13 12:39:02 2013 UTC (11 years, 3 months ago) by dl
Branch: MAIN
Changes since 1.99: +2 -17 lines
Log Message:
Synch with lambda Spliterator API

File Contents

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