ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/CopyOnWriteArrayList.java
Revision: 1.32
Committed: Tue Apr 26 23:46:37 2005 UTC (19 years, 1 month ago) by jsr166
Branch: MAIN
Changes since 1.31: +42 -41 lines
Log Message:
doc fixes

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     import java.util.*;
19    
20     /**
21 dl 1.28 * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
22 dl 1.4 * operations (add, set, and so on) are implemented by making a fresh
23 jsr166 1.30 * copy of the underlying array.
24 tim 1.1 *
25 dl 1.26 * <p> This is ordinarily too costly, but may be <em>more</em> efficient
26 dl 1.12 * than alternatives when traversal operations vastly outnumber
27     * mutations, and is useful when you cannot or don't want to
28     * synchronize traversals, yet need to preclude interference among
29 dl 1.15 * concurrent threads. The "snapshot" style iterator method uses a
30     * reference to the state of the array at the point that the iterator
31     * was created. This array never changes during the lifetime of the
32     * iterator, so interference is impossible and the iterator is
33     * guaranteed not to throw <tt>ConcurrentModificationException</tt>.
34     * The iterator will not reflect additions, removals, or changes to
35     * the list since the iterator was created. Element-changing
36     * operations on iterators themselves (remove, set, and add) are not
37     * supported. These methods throw
38     * <tt>UnsupportedOperationException</tt>.
39 dl 1.24 *
40     * <p>This class is a member of the
41     * <a href="{@docRoot}/../guide/collections/index.html">
42     * Java Collections Framework</a>.
43     *
44 dl 1.6 * @since 1.5
45     * @author Doug Lea
46 dl 1.19 * @param <E> the type of elements held in this collection
47 dl 1.6 */
48 tim 1.1 public class CopyOnWriteArrayList<E>
49     implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
50 dl 1.11 private static final long serialVersionUID = 8673264195747942595L;
51 tim 1.1
52     /**
53 dl 1.6 * The held array. Directly accessed only within synchronized
54 tim 1.1 * methods
55     */
56 dl 1.12 private volatile transient E[] array;
57 tim 1.1
58     /**
59     * Accessor to the array intended to be called from
60     * within unsynchronized read-only methods
61 jsr166 1.30 */
62 dl 1.12 private E[] array() { return array; }
63 tim 1.1
64     /**
65 dl 1.15 * Creates an empty list.
66 tim 1.1 */
67     public CopyOnWriteArrayList() {
68 dl 1.12 array = (E[]) new Object[0];
69 tim 1.1 }
70    
71     /**
72 dl 1.15 * Creates a list containing the elements of the specified
73 jsr166 1.32 * collection, in the order they are returned by the collection's
74 tim 1.1 * iterator.
75 jsr166 1.32 *
76 dl 1.6 * @param c the collection of initially held elements
77 tim 1.1 */
78 tim 1.22 public CopyOnWriteArrayList(Collection<? extends E> c) {
79 dl 1.12 array = (E[]) new Object[c.size()];
80 tim 1.22 Iterator<? extends E> i = c.iterator();
81 tim 1.1 int size = 0;
82     while (i.hasNext())
83 dl 1.12 array[size++] = i.next();
84 tim 1.1 }
85    
86     /**
87 jsr166 1.30 * Creates a new CopyOnWriteArrayList holding a copy of given array.
88 tim 1.9 *
89     * @param toCopyIn the array (a copy of this array is used as the
90     * internal array)
91 jsr166 1.30 */
92 tim 1.1 public CopyOnWriteArrayList(E[] toCopyIn) {
93     copyIn(toCopyIn, 0, toCopyIn.length);
94     }
95    
96     /**
97 jsr166 1.30 * Replaces the held array with a copy of the <tt>n</tt> elements
98 dl 1.25 * of the provided array, starting at position <tt>first</tt>. To
99     * copy an entire array, call with arguments (array, 0,
100     * array.length).
101 tim 1.1 * @param toCopyIn the array. A copy of the indicated elements of
102 dl 1.25 * this array is used as the internal array.
103 tim 1.1 * @param first The index of first position of the array to
104     * start copying from.
105     * @param n the number of elements to copy. This will be the new size of
106     * the list.
107 jsr166 1.30 */
108 tim 1.1 private synchronized void copyIn(E[] toCopyIn, int first, int n) {
109 dl 1.12 array = (E[]) new Object[n];
110     System.arraycopy(toCopyIn, first, array, 0, n);
111 tim 1.1 }
112    
113     /**
114 dl 1.15 * Returns the number of elements in this list.
115 tim 1.1 *
116 dl 1.15 * @return the number of elements in this list.
117 tim 1.1 */
118     public int size() {
119     return array().length;
120     }
121    
122     /**
123 dl 1.15 * Tests if this list has no elements.
124 tim 1.1 *
125 dl 1.15 * @return <tt>true</tt> if this list has no elements;
126 dl 1.14 * <tt>false</tt> otherwise.
127 tim 1.1 */
128     public boolean isEmpty() {
129     return size() == 0;
130     }
131    
132     /**
133 dl 1.15 * Returns <tt>true</tt> if this list contains the specified element.
134 tim 1.1 *
135 dl 1.6 * @param elem element whose presence in this List is to be tested.
136 dl 1.15 * @return <code>true</code> if the specified element is present;
137 tim 1.22 * <code>false</code> otherwise.
138 tim 1.1 */
139     public boolean contains(Object elem) {
140     E[] elementData = array();
141     int len = elementData.length;
142     return indexOf(elem, elementData, len) >= 0;
143     }
144    
145     /**
146 jsr166 1.30 * Searches for the first occurrence of the given argument, testing
147     * for equality using the <tt>equals</tt> method.
148 tim 1.1 *
149     * @param elem an object.
150     * @return the index of the first occurrence of the argument in this
151 dl 1.14 * list; returns <tt>-1</tt> if the object is not found.
152 tim 1.1 * @see Object#equals(Object)
153     */
154     public int indexOf(Object elem) {
155     E[] elementData = array();
156     int len = elementData.length;
157     return indexOf(elem, elementData, len);
158     }
159    
160     /**
161     * static version allows repeated call without needed
162     * to grab lock for array each time
163 jsr166 1.30 */
164 tim 1.1 private static int indexOf(Object elem, Object[] elementData, int len) {
165     if (elem == null) {
166     for (int i = 0; i < len; i++)
167     if (elementData[i]==null)
168     return i;
169     } else {
170     for (int i = 0; i < len; i++)
171     if (elem.equals(elementData[i]))
172     return i;
173     }
174     return -1;
175     }
176    
177     /**
178 dl 1.16 * Searches for the first occurrence of the given argument, beginning
179 dl 1.14 * the search at <tt>index</tt>, and testing for equality using
180     * the <tt>equals</tt> method.
181 tim 1.1 *
182     * @param elem an object.
183     * @param index the index to start searching from.
184     * @return the index of the first occurrence of the object argument in
185 dl 1.14 * this List at position <tt>index</tt> or later in the
186     * List; returns <tt>-1</tt> if the object is not found.
187 tim 1.1 * @see Object#equals(Object)
188     */
189     public int indexOf(E elem, int index) {
190     E[] elementData = array();
191     int elementCount = elementData.length;
192    
193     if (elem == null) {
194     for (int i = index ; i < elementCount ; i++)
195     if (elementData[i]==null)
196     return i;
197     } else {
198     for (int i = index ; i < elementCount ; i++)
199     if (elem.equals(elementData[i]))
200     return i;
201     }
202     return -1;
203     }
204    
205     /**
206     * Returns the index of the last occurrence of the specified object in
207     * this list.
208     *
209 dl 1.15 * @param elem the desired element.
210 tim 1.1 * @return the index of the last occurrence of the specified object in
211     * this list; returns -1 if the object is not found.
212     */
213     public int lastIndexOf(Object elem) {
214     E[] elementData = array();
215     int len = elementData.length;
216     return lastIndexOf(elem, elementData, len);
217     }
218    
219     private static int lastIndexOf(Object elem, Object[] elementData, int len) {
220     if (elem == null) {
221     for (int i = len-1; i >= 0; i--)
222     if (elementData[i]==null)
223     return i;
224     } else {
225     for (int i = len-1; i >= 0; i--)
226     if (elem.equals(elementData[i]))
227     return i;
228     }
229     return -1;
230     }
231    
232     /**
233     * Searches backwards for the specified object, starting from the
234     * specified index, and returns an index to it.
235     *
236 dl 1.15 * @param elem the desired element.
237 tim 1.1 * @param index the index to start searching from.
238     * @return the index of the last occurrence of the specified object in this
239     * List at position less than index in the List;
240     * -1 if the object is not found.
241     */
242     public int lastIndexOf(E elem, int index) {
243     // needed in order to compile on 1.2b3
244     E[] elementData = array();
245     if (elem == null) {
246     for (int i = index; i >= 0; i--)
247     if (elementData[i]==null)
248     return i;
249     } else {
250     for (int i = index; i >= 0; i--)
251     if (elem.equals(elementData[i]))
252     return i;
253     }
254     return -1;
255     }
256    
257     /**
258     * Returns a shallow copy of this list. (The elements themselves
259     * are not copied.)
260     *
261     * @return a clone of this list.
262     */
263     public Object clone() {
264     try {
265     E[] elementData = array();
266 tim 1.8 CopyOnWriteArrayList<E> v = (CopyOnWriteArrayList<E>)super.clone();
267 dl 1.12 v.array = (E[]) new Object[elementData.length];
268     System.arraycopy(elementData, 0, v.array, 0, elementData.length);
269 tim 1.1 return v;
270     } catch (CloneNotSupportedException e) {
271     // this shouldn't happen, since we are Cloneable
272     throw new InternalError();
273     }
274     }
275    
276     /**
277     * Returns an array containing all of the elements in this list
278     * in the correct order.
279 dl 1.15 * @return an array containing all of the elements in this list
280 tim 1.22 * in the correct order.
281 tim 1.1 */
282     public Object[] toArray() {
283     Object[] elementData = array();
284     Object[] result = new Object[elementData.length];
285     System.arraycopy(elementData, 0, result, 0, elementData.length);
286     return result;
287     }
288    
289     /**
290     * Returns an array containing all of the elements in this list in the
291     * correct order. The runtime type of the returned array is that of the
292     * specified array. If the list fits in the specified array, it is
293     * returned therein. Otherwise, a new array is allocated with the runtime
294     * type of the specified array and the size of this list.
295 jsr166 1.32 *
296     * <p>If this list fits in the specified array with room to spare
297     * (i.e., the array has more elements than this list), the element
298     * in the array immediately following the end of the list is set to
299     * <tt>null</tt>. This is useful in determining the length of this
300     * list <i>only</i> if the caller knows that this collection does
301     * not contain any <tt>null</tt> elements.)
302 tim 1.1 *
303     * @param a the array into which the elements of the list are to
304     * be stored, if it is big enough; otherwise, a new array of the
305     * same runtime type is allocated for this purpose.
306     * @return an array containing the elements of the list.
307 dl 1.29 * @throws ArrayStoreException if the runtime type of a is not a supertype
308 tim 1.1 * of the runtime type of every element in this list.
309     */
310     public <T> T[] toArray(T a[]) {
311     E[] elementData = array();
312    
313     if (a.length < elementData.length)
314     a = (T[])
315     java.lang.reflect.Array.newInstance(a.getClass().getComponentType(),
316     elementData.length);
317    
318     System.arraycopy(elementData, 0, a, 0, elementData.length);
319    
320     if (a.length > elementData.length)
321     a[elementData.length] = null;
322    
323     return a;
324     }
325    
326     // Positional Access Operations
327    
328     /**
329     * Returns the element at the specified position in this list.
330     *
331 dl 1.15 * @param index index of element to return.
332     * @return the element at the specified position in this list.
333 jsr166 1.31 * @throws IndexOutOfBoundsException if the index is out of range
334     * (<tt>index &lt; 0 || index &gt; size()</tt>).
335 tim 1.1 */
336     public E get(int index) {
337     E[] elementData = array();
338     rangeCheck(index, elementData.length);
339     return elementData[index];
340     }
341    
342     /**
343     * Replaces the element at the specified position in this list with
344     * the specified element.
345     *
346     * @param index index of element to replace.
347     * @param element element to be stored at the specified position.
348     * @return the element previously at the specified position.
349 jsr166 1.31 * @throws IndexOutOfBoundsException if the index is out of range
350     * (<tt>index &lt; 0 || index &gt; size()</tt>).
351 tim 1.1 */
352     public synchronized E set(int index, E element) {
353 dl 1.12 int len = array.length;
354 tim 1.1 rangeCheck(index, len);
355 dl 1.12 E oldValue = array[index];
356 tim 1.1
357     boolean same = (oldValue == element ||
358     (element != null && element.equals(oldValue)));
359     if (!same) {
360 tim 1.7 E[] newArray = (E[]) new Object[len];
361 dl 1.12 System.arraycopy(array, 0, newArray, 0, len);
362 tim 1.1 newArray[index] = element;
363 dl 1.12 array = newArray;
364 tim 1.1 }
365     return oldValue;
366     }
367    
368     /**
369     * Appends the specified element to the end of this list.
370     *
371     * @param element element to be appended to this list.
372 jsr166 1.32 * @return true (as per the general contract of <tt>Collection.add</tt>).
373 tim 1.1 */
374     public synchronized boolean add(E element) {
375 dl 1.12 int len = array.length;
376 tim 1.7 E[] newArray = (E[]) new Object[len+1];
377 dl 1.12 System.arraycopy(array, 0, newArray, 0, len);
378 tim 1.1 newArray[len] = element;
379 dl 1.12 array = newArray;
380 tim 1.1 return true;
381     }
382    
383     /**
384     * Inserts the specified element at the specified position in this
385     * list. Shifts the element currently at that position (if any) and
386     * any subsequent elements to the right (adds one to their indices).
387     *
388     * @param index index at which the specified element is to be inserted.
389     * @param element element to be inserted.
390 jsr166 1.31 * @throws IndexOutOfBoundsException if the index is out of range
391     * (<tt>index &lt; 0 || index &gt; size()</tt>).
392 tim 1.1 */
393     public synchronized void add(int index, E element) {
394 dl 1.12 int len = array.length;
395 tim 1.1 if (index > len || index < 0)
396     throw new IndexOutOfBoundsException("Index: "+index+", Size: "+len);
397    
398 tim 1.7 E[] newArray = (E[]) new Object[len+1];
399 dl 1.12 System.arraycopy(array, 0, newArray, 0, index);
400 tim 1.1 newArray[index] = element;
401 dl 1.12 System.arraycopy(array, index, newArray, index+1, len - index);
402     array = newArray;
403 tim 1.1 }
404    
405     /**
406     * Removes the element at the specified position in this list.
407     * Shifts any subsequent elements to the left (subtracts one from their
408 dl 1.15 * indices).
409 tim 1.1 *
410     * @param index the index of the element to removed.
411 dl 1.15 * @return the element that was removed from the list.
412 jsr166 1.31 * @throws IndexOutOfBoundsException if the index is out of range
413     * (<tt>index &lt; 0 || index &gt; size()</tt>).
414 tim 1.1 */
415     public synchronized E remove(int index) {
416 dl 1.12 int len = array.length;
417 tim 1.1 rangeCheck(index, len);
418 dl 1.12 E oldValue = array[index];
419 tim 1.7 E[] newArray = (E[]) new Object[len-1];
420 dl 1.12 System.arraycopy(array, 0, newArray, 0, index);
421 tim 1.1 int numMoved = len - index - 1;
422     if (numMoved > 0)
423 dl 1.12 System.arraycopy(array, index+1, newArray, index, numMoved);
424     array = newArray;
425 tim 1.1 return oldValue;
426     }
427    
428     /**
429 dl 1.15 * Removes a single instance of the specified element from this
430     * list, if it is present (optional operation). More formally,
431     * removes an element <tt>e</tt> such that <tt>(o==null ? e==null :
432     * o.equals(e))</tt>, if the list contains one or more such
433     * elements. Returns <tt>true</tt> if the list contained the
434     * specified element (or equivalently, if the list changed as a
435     * result of the call).<p>
436 tim 1.1 *
437 dl 1.15 * @param o element to be removed from this list, if present.
438     * @return <tt>true</tt> if the list contained the specified element.
439 tim 1.1 */
440 dl 1.15 public synchronized boolean remove(Object o) {
441 dl 1.12 int len = array.length;
442 tim 1.1 if (len == 0) return false;
443    
444     // Copy while searching for element to remove
445     // This wins in the normal case of element being present
446    
447     int newlen = len-1;
448 tim 1.7 E[] newArray = (E[]) new Object[newlen];
449 tim 1.1
450     for (int i = 0; i < newlen; ++i) {
451 dl 1.15 if (o == array[i] ||
452     (o != null && o.equals(array[i]))) {
453 tim 1.1 // found one; copy remaining and exit
454 dl 1.12 for (int k = i + 1; k < len; ++k) newArray[k-1] = array[k];
455     array = newArray;
456 tim 1.1 return true;
457 tim 1.10 } else
458 dl 1.12 newArray[i] = array[i];
459 tim 1.1 }
460     // special handling for last cell
461    
462 dl 1.15 if (o == array[newlen] ||
463     (o != null && o.equals(array[newlen]))) {
464 dl 1.12 array = newArray;
465 tim 1.1 return true;
466 tim 1.10 } else
467 tim 1.1 return false; // throw away copy
468     }
469    
470    
471     /**
472     * Removes from this List all of the elements whose index is between
473     * fromIndex, inclusive and toIndex, exclusive. Shifts any succeeding
474     * elements to the left (reduces their index).
475 dl 1.15 * This call shortens the list by <tt>(toIndex - fromIndex)</tt> elements.
476     * (If <tt>toIndex==fromIndex</tt>, this operation has no effect.)
477 tim 1.1 *
478     * @param fromIndex index of first element to be removed.
479 dl 1.6 * @param toIndex index after last element to be removed.
480 dl 1.29 * @throws IndexOutOfBoundsException if fromIndex or toIndex out of
481 tim 1.1 * range (fromIndex &lt; 0 || fromIndex &gt;= size() || toIndex
482     * &gt; size() || toIndex &lt; fromIndex).
483     */
484     private synchronized void removeRange(int fromIndex, int toIndex) {
485 dl 1.12 int len = array.length;
486 tim 1.1
487     if (fromIndex < 0 || fromIndex >= len ||
488     toIndex > len || toIndex < fromIndex)
489     throw new IndexOutOfBoundsException();
490    
491     int numMoved = len - toIndex;
492     int newlen = len - (toIndex-fromIndex);
493 tim 1.7 E[] newArray = (E[]) new Object[newlen];
494 dl 1.12 System.arraycopy(array, 0, newArray, 0, fromIndex);
495     System.arraycopy(array, toIndex, newArray, fromIndex, numMoved);
496     array = newArray;
497 tim 1.1 }
498    
499    
500     /**
501     * Append the element if not present.
502 jsr166 1.32 * @param element element to be added to this list, if absent.
503 tim 1.1 * @return true if added
504 jsr166 1.30 */
505 tim 1.1 public synchronized boolean addIfAbsent(E element) {
506     // Copy while checking if already present.
507     // This wins in the most common case where it is not present
508 dl 1.12 int len = array.length;
509 tim 1.7 E[] newArray = (E[]) new Object[len + 1];
510 tim 1.1 for (int i = 0; i < len; ++i) {
511 dl 1.12 if (element == array[i] ||
512     (element != null && element.equals(array[i])))
513 tim 1.1 return false; // exit, throwing away copy
514     else
515 dl 1.12 newArray[i] = array[i];
516 tim 1.1 }
517     newArray[len] = element;
518 dl 1.12 array = newArray;
519 tim 1.1 return true;
520     }
521    
522     /**
523 jsr166 1.32 * Returns true if this list contains all of the elements in the
524     * specified collection.
525     *
526     * <p>This implementation iterates over the specified collection,
527     * checking each element returned by the Iterator in turn to see if
528     * it's contained in this list. If all elements are so contained
529     * <tt>true</tt> is returned, otherwise <tt>false</tt>.
530     *
531 dl 1.6 * @param c the collection
532     * @return true if all elements are contained
533 tim 1.1 */
534 tim 1.7 public boolean containsAll(Collection<?> c) {
535 tim 1.1 E[] elementData = array();
536     int len = elementData.length;
537 tim 1.7 Iterator e = c.iterator();
538 tim 1.1 while (e.hasNext())
539 dl 1.20 if (indexOf(e.next(), elementData, len) < 0)
540 tim 1.1 return false;
541    
542     return true;
543     }
544    
545    
546     /**
547 jsr166 1.32 * Removes from this list all of its elements that are contained in
548     * the specified collection. This is a particularly expensive operation
549 tim 1.1 * in this class because of the need for an internal temporary array.
550     *
551 dl 1.6 * @param c the collection
552 jsr166 1.32 * @return true if this list changed as a result of the call.
553 tim 1.1 */
554 tim 1.7 public synchronized boolean removeAll(Collection<?> c) {
555 dl 1.12 E[] elementData = array;
556 tim 1.1 int len = elementData.length;
557     if (len == 0) return false;
558    
559     // temp array holds those elements we know we want to keep
560 tim 1.7 E[] temp = (E[]) new Object[len];
561 tim 1.1 int newlen = 0;
562     for (int i = 0; i < len; ++i) {
563     E element = elementData[i];
564     if (!c.contains(element)) {
565     temp[newlen++] = element;
566     }
567     }
568    
569     if (newlen == len) return false;
570    
571     // copy temp as new array
572 tim 1.7 E[] newArray = (E[]) new Object[newlen];
573 tim 1.1 System.arraycopy(temp, 0, newArray, 0, newlen);
574 dl 1.12 array = newArray;
575 tim 1.1 return true;
576     }
577    
578     /**
579 jsr166 1.32 * Retains only the elements in this list that are contained in the
580     * specified collection (optional operation). In other words, removes
581     * from this list all of its elements that are not contained in the
582     * specified collection.
583     *
584 dl 1.6 * @param c the collection
585 jsr166 1.32 * @return true if this list changed as a result of the call.
586 tim 1.1 */
587 tim 1.7 public synchronized boolean retainAll(Collection<?> c) {
588 dl 1.12 E[] elementData = array;
589 tim 1.1 int len = elementData.length;
590     if (len == 0) return false;
591    
592 tim 1.7 E[] temp = (E[]) new Object[len];
593 tim 1.1 int newlen = 0;
594     for (int i = 0; i < len; ++i) {
595     E element = elementData[i];
596     if (c.contains(element)) {
597     temp[newlen++] = element;
598     }
599     }
600    
601     if (newlen == len) return false;
602    
603 tim 1.7 E[] newArray = (E[]) new Object[newlen];
604 tim 1.1 System.arraycopy(temp, 0, newArray, 0, newlen);
605 dl 1.12 array = newArray;
606 tim 1.1 return true;
607     }
608    
609     /**
610 jsr166 1.32 * Appends all of the elements in the specified collection that
611 tim 1.1 * are not already contained in this list, to the end of
612     * this list, in the order that they are returned by the
613 jsr166 1.32 * specified collection's iterator.
614 tim 1.1 *
615 jsr166 1.32 * @param c elements to be added to this list.
616 tim 1.1 * @return the number of elements added
617     */
618 tim 1.7 public synchronized int addAllAbsent(Collection<? extends E> c) {
619 tim 1.1 int numNew = c.size();
620     if (numNew == 0) return 0;
621    
622 dl 1.12 E[] elementData = array;
623 tim 1.1 int len = elementData.length;
624    
625 tim 1.7 E[] temp = (E[]) new Object[numNew];
626 tim 1.1 int added = 0;
627 dl 1.20 Iterator<? extends E> e = c.iterator();
628 tim 1.1 while (e.hasNext()) {
629 dl 1.20 E element = e.next();
630 tim 1.1 if (indexOf(element, elementData, len) < 0) {
631     if (indexOf(element, temp, added) < 0) {
632     temp[added++] = element;
633     }
634     }
635     }
636    
637     if (added == 0) return 0;
638    
639 tim 1.7 E[] newArray = (E[]) new Object[len+added];
640 tim 1.1 System.arraycopy(elementData, 0, newArray, 0, len);
641     System.arraycopy(temp, 0, newArray, len, added);
642 dl 1.12 array = newArray;
643 tim 1.1 return added;
644     }
645    
646     /**
647     * Removes all of the elements from this list.
648     *
649     */
650     public synchronized void clear() {
651 dl 1.12 array = (E[]) new Object[0];
652 tim 1.1 }
653    
654     /**
655 jsr166 1.32 * Appends all of the elements in the specified collection to the end
656     * of this list, in the order that they are returned by the specified
657     * collection's iterator.
658 tim 1.1 *
659     * @param c elements to be inserted into this list.
660 dl 1.6 * @return true if any elements are added
661 tim 1.1 */
662 tim 1.7 public synchronized boolean addAll(Collection<? extends E> c) {
663 tim 1.1 int numNew = c.size();
664     if (numNew == 0) return false;
665    
666 dl 1.12 int len = array.length;
667 tim 1.7 E[] newArray = (E[]) new Object[len+numNew];
668 dl 1.12 System.arraycopy(array, 0, newArray, 0, len);
669 dl 1.20 Iterator<? extends E> e = c.iterator();
670 tim 1.1 for (int i=0; i<numNew; i++)
671 dl 1.20 newArray[len++] = e.next();
672 dl 1.12 array = newArray;
673 tim 1.1
674     return true;
675     }
676    
677     /**
678     * Inserts all of the elements in the specified Collection into this
679     * list, starting at the specified position. Shifts the element
680     * currently at that position (if any) and any subsequent elements to
681     * the right (increases their indices). The new elements will appear
682     * in the list in the order that they are returned by the
683     * specified Collection's iterator.
684     *
685     * @param index index at which to insert first element
686     * from the specified collection.
687     * @param c elements to be inserted into this list.
688 jsr166 1.31 * @throws IndexOutOfBoundsException if the index is out of range
689     * (<tt>index &lt; 0 || index &gt; size()</tt>).
690 dl 1.6 * @return true if any elements are added
691 tim 1.1 */
692 tim 1.7 public synchronized boolean addAll(int index, Collection<? extends E> c) {
693 dl 1.12 int len = array.length;
694 tim 1.1 if (index > len || index < 0)
695     throw new IndexOutOfBoundsException("Index: "+index+", Size: "+len);
696    
697     int numNew = c.size();
698     if (numNew == 0) return false;
699    
700 tim 1.7 E[] newArray = (E[]) new Object[len+numNew];
701 dl 1.12 System.arraycopy(array, 0, newArray, 0, len);
702 tim 1.1 int numMoved = len - index;
703     if (numMoved > 0)
704 dl 1.12 System.arraycopy(array, index, newArray, index + numNew, numMoved);
705 dl 1.20 Iterator<? extends E> e = c.iterator();
706 tim 1.1 for (int i=0; i<numNew; i++)
707 dl 1.20 newArray[index++] = e.next();
708 dl 1.12 array = newArray;
709 tim 1.1
710     return true;
711     }
712    
713     /**
714 jsr166 1.30 * Checks if the given index is in range. If not, throws an appropriate
715 tim 1.1 * runtime exception.
716     */
717     private void rangeCheck(int index, int length) {
718     if (index >= length || index < 0)
719     throw new IndexOutOfBoundsException("Index: "+index+", Size: "+ length);
720     }
721    
722     /**
723     * Save the state of the list to a stream (i.e., serialize it).
724     *
725     * @serialData The length of the array backing the list is emitted
726     * (int), followed by all of its elements (each an Object)
727     * in the proper order.
728 dl 1.6 * @param s the stream
729 tim 1.1 */
730     private void writeObject(java.io.ObjectOutputStream s)
731     throws java.io.IOException{
732    
733     // Write out element count, and any hidden stuff
734     s.defaultWriteObject();
735    
736     E[] elementData = array();
737     // Write out array length
738     s.writeInt(elementData.length);
739    
740     // Write out all elements in the proper order.
741     for (int i=0; i<elementData.length; i++)
742     s.writeObject(elementData[i]);
743     }
744    
745     /**
746     * Reconstitute the list from a stream (i.e., deserialize it).
747 dl 1.6 * @param s the stream
748 tim 1.1 */
749 dl 1.12 private void readObject(java.io.ObjectInputStream s)
750 tim 1.1 throws java.io.IOException, ClassNotFoundException {
751    
752     // Read in size, and any hidden stuff
753     s.defaultReadObject();
754    
755     // Read in array length and allocate array
756     int arrayLength = s.readInt();
757 tim 1.7 E[] elementData = (E[]) new Object[arrayLength];
758 tim 1.1
759     // Read in all elements in the proper order.
760     for (int i=0; i<elementData.length; i++)
761     elementData[i] = (E) s.readObject();
762 dl 1.12 array = elementData;
763 tim 1.1 }
764    
765     /**
766 jsr166 1.32 * Returns a string representation of this list, containing
767 tim 1.1 * the String representation of each element.
768     */
769     public String toString() {
770     StringBuffer buf = new StringBuffer();
771     Iterator e = iterator();
772     buf.append("[");
773     int maxIndex = size() - 1;
774     for (int i = 0; i <= maxIndex; i++) {
775     buf.append(String.valueOf(e.next()));
776     if (i < maxIndex)
777     buf.append(", ");
778     }
779     buf.append("]");
780     return buf.toString();
781     }
782    
783    
784     /**
785     * Compares the specified Object with this List for equality. Returns true
786     * if and only if the specified Object is also a List, both Lists have the
787     * same size, and all corresponding pairs of elements in the two Lists are
788 dl 1.14 * <em>equal</em>. (Two elements <tt>e1</tt> and <tt>e2</tt> are
789     * <em>equal</em> if <tt>(e1==null ? e2==null : e1.equals(e2))</tt>.)
790 tim 1.1 * In other words, two Lists are defined to be equal if they contain the
791     * same elements in the same order.
792     * <p>
793     * This implementation first checks if the specified object is this
794     * List. If so, it returns true; if not, it checks if the specified
795     * object is a List. If not, it returns false; if so, it iterates over
796     * both lists, comparing corresponding pairs of elements. If any
797     * comparison returns false, this method returns false. If either
798 dl 1.27 * Iterator runs out of elements before the other it returns false
799 tim 1.1 * (as the Lists are of unequal length); otherwise it returns true when
800     * the iterations complete.
801     *
802     * @param o the Object to be compared for equality with this List.
803     * @return true if the specified Object is equal to this List.
804     */
805     public boolean equals(Object o) {
806     if (o == this)
807     return true;
808     if (!(o instanceof List))
809     return false;
810    
811 tim 1.8 List<E> l2 = (List<E>)(o);
812 tim 1.1 if (size() != l2.size())
813     return false;
814    
815     ListIterator<E> e1 = listIterator();
816     ListIterator<E> e2 = l2.listIterator();
817     while(e1.hasNext()) {
818     E o1 = e1.next();
819     E o2 = e2.next();
820     if (!(o1==null ? o2==null : o1.equals(o2)))
821     return false;
822     }
823     return true;
824     }
825    
826     /**
827 jsr166 1.30 * Returns the hash code value for this List.
828 dl 1.26 *
829     * <p> This implementation uses the definition in {@link
830     * List#hashCode}.
831 dl 1.15 * @return the hash code
832 tim 1.1 */
833     public int hashCode() {
834     int hashCode = 1;
835     Iterator<E> i = iterator();
836     while (i.hasNext()) {
837     E obj = i.next();
838     hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
839     }
840     return hashCode;
841     }
842    
843     /**
844 jsr166 1.32 * Returns an Iterator over the elements contained in this list.
845 tim 1.1 * The iterator provides a snapshot of the state of the list
846     * when the iterator was constructed. No synchronization is
847     * needed while traversing the iterator. The iterator does
848 dl 1.14 * <em>NOT</em> support the <tt>remove</tt> method.
849 dl 1.23 * @return the iterator
850 tim 1.1 */
851     public Iterator<E> iterator() {
852     return new COWIterator<E>(array(), 0);
853     }
854    
855     /**
856     * Returns an Iterator of the elements in this List (in proper sequence).
857     * The iterator provides a snapshot of the state of the list
858     * when the iterator was constructed. No synchronization is
859     * needed while traversing the iterator. The iterator does
860 dl 1.14 * <em>NOT</em> support the <tt>remove</tt>, <tt>set</tt>,
861     * or <tt>add</tt> methods.
862 dl 1.23 * @return the iterator
863 tim 1.1 *
864     */
865     public ListIterator<E> listIterator() {
866     return new COWIterator<E>(array(), 0);
867     }
868    
869     /**
870     * Returns a ListIterator of the elements in this List (in proper
871     * sequence), starting at the specified position in the List. The
872     * specified index indicates the first element that would be returned by
873     * an initial call to nextElement. An initial call to previousElement
874     * would return the element with the specified index minus one.
875     * The ListIterator returned by this implementation will throw
876     * an UnsupportedOperationException in its remove, set and
877     * add methods.
878     *
879     * @param index index of first element to be returned from the
880     * ListIterator (by a call to getNext).
881 dl 1.23 * @return the iterator
882 jsr166 1.31 * @throws IndexOutOfBoundsException if the index is out of range
883     * (<tt>index &lt; 0 || index &gt; size()</tt>).
884 tim 1.1 */
885     public ListIterator<E> listIterator(final int index) {
886     E[] elementData = array();
887     int len = elementData.length;
888     if (index<0 || index>len)
889     throw new IndexOutOfBoundsException("Index: "+index);
890    
891     return new COWIterator<E>(array(), index);
892     }
893    
894     private static class COWIterator<E> implements ListIterator<E> {
895    
896     /** Snapshot of the array **/
897     private final E[] array;
898    
899     /**
900     * Index of element to be returned by subsequent call to next.
901     */
902     private int cursor;
903    
904     private COWIterator(E[] elementArray, int initialCursor) {
905     array = elementArray;
906     cursor = initialCursor;
907     }
908    
909     public boolean hasNext() {
910     return cursor < array.length;
911     }
912    
913     public boolean hasPrevious() {
914     return cursor > 0;
915     }
916    
917     public E next() {
918     try {
919     return array[cursor++];
920 tim 1.10 } catch (IndexOutOfBoundsException ex) {
921 tim 1.1 throw new NoSuchElementException();
922     }
923     }
924    
925     public E previous() {
926     try {
927     return array[--cursor];
928 jsr166 1.30 } catch (IndexOutOfBoundsException e) {
929 tim 1.1 throw new NoSuchElementException();
930     }
931     }
932    
933     public int nextIndex() {
934     return cursor;
935     }
936    
937     public int previousIndex() {
938     return cursor-1;
939     }
940    
941     /**
942     * Not supported. Always throws UnsupportedOperationException.
943 jsr166 1.32 * @throws UnsupportedOperationException always; <tt>remove</tt>
944     * is not supported by this iterator.
945 tim 1.1 */
946     public void remove() {
947     throw new UnsupportedOperationException();
948     }
949    
950     /**
951     * Not supported. Always throws UnsupportedOperationException.
952 jsr166 1.32 * @throws UnsupportedOperationException always; <tt>set</tt>
953     * is not supported by this iterator.
954 tim 1.1 */
955     public void set(E o) {
956     throw new UnsupportedOperationException();
957     }
958    
959     /**
960     * Not supported. Always throws UnsupportedOperationException.
961 jsr166 1.32 * @throws UnsupportedOperationException always; <tt>add</tt>
962     * is not supported by this iterator.
963 tim 1.1 */
964     public void add(E o) {
965     throw new UnsupportedOperationException();
966     }
967     }
968    
969    
970     /**
971     * Returns a view of the portion of this List between fromIndex,
972     * inclusive, and toIndex, exclusive. The returned List is backed by this
973     * List, so changes in the returned List are reflected in this List, and
974     * vice-versa. While mutative operations are supported, they are
975 dl 1.16 * probably not very useful for CopyOnWriteArrayLists.
976 tim 1.9 * <p>
977 tim 1.1 * The semantics of the List returned by this method become undefined if
978     * the backing list (i.e., this List) is <i>structurally modified</i> in
979     * any way other than via the returned List. (Structural modifications are
980     * those that change the size of the List, or otherwise perturb it in such
981     * a fashion that iterations in progress may yield incorrect results.)
982     *
983     * @param fromIndex low endpoint (inclusive) of the subList.
984 dl 1.6 * @param toIndex high endpoint (exclusive) of the subList.
985 tim 1.1 * @return a view of the specified range within this List.
986 jsr166 1.30 * @throws IndexOutOfBoundsException if
987 tim 1.1 * (fromIndex &lt; 0 || toIndex &gt; size || fromIndex &gt; toIndex).
988     */
989     public synchronized List<E> subList(int fromIndex, int toIndex) {
990 dl 1.21 // synchronized since sublist constructor depends on it.
991 dl 1.12 int len = array.length;
992 tim 1.1 if (fromIndex<0 || toIndex>len || fromIndex>toIndex)
993     throw new IndexOutOfBoundsException();
994     return new COWSubList<E>(this, fromIndex, toIndex);
995     }
996    
997     private static class COWSubList<E> extends AbstractList<E> {
998    
999     /*
1000 dl 1.2 This class extends AbstractList merely for convenience, to
1001     avoid having to define addAll, etc. This doesn't hurt, but
1002     is wasteful. This class does not need or use modCount
1003     mechanics in AbstractList, but does need to check for
1004     concurrent modification using similar mechanics. On each
1005     operation, the array that we expect the backing list to use
1006     is checked and updated. Since we do this for all of the
1007     base operations invoked by those defined in AbstractList,
1008     all is well. While inefficient, this is not worth
1009     improving. The kinds of list operations inherited from
1010 dl 1.20 AbstractList are already so slow on COW sublists that
1011 dl 1.2 adding a bit more space/time doesn't seem even noticeable.
1012 tim 1.1 */
1013    
1014     private final CopyOnWriteArrayList<E> l;
1015     private final int offset;
1016     private int size;
1017     private E[] expectedArray;
1018    
1019     private COWSubList(CopyOnWriteArrayList<E> list,
1020     int fromIndex, int toIndex) {
1021     l = list;
1022     expectedArray = l.array();
1023     offset = fromIndex;
1024     size = toIndex - fromIndex;
1025     }
1026    
1027     // only call this holding l's lock
1028     private void checkForComodification() {
1029 dl 1.12 if (l.array != expectedArray)
1030 tim 1.1 throw new ConcurrentModificationException();
1031     }
1032    
1033     // only call this holding l's lock
1034     private void rangeCheck(int index) {
1035     if (index<0 || index>=size)
1036     throw new IndexOutOfBoundsException("Index: "+index+ ",Size: "+size);
1037     }
1038    
1039    
1040     public E set(int index, E element) {
1041     synchronized(l) {
1042     rangeCheck(index);
1043     checkForComodification();
1044     E x = l.set(index+offset, element);
1045 dl 1.12 expectedArray = l.array;
1046 tim 1.1 return x;
1047     }
1048     }
1049    
1050     public E get(int index) {
1051     synchronized(l) {
1052     rangeCheck(index);
1053     checkForComodification();
1054     return l.get(index+offset);
1055     }
1056     }
1057    
1058     public int size() {
1059     synchronized(l) {
1060     checkForComodification();
1061     return size;
1062     }
1063     }
1064    
1065     public void add(int index, E element) {
1066     synchronized(l) {
1067     checkForComodification();
1068     if (index<0 || index>size)
1069     throw new IndexOutOfBoundsException();
1070     l.add(index+offset, element);
1071 dl 1.12 expectedArray = l.array;
1072 tim 1.1 size++;
1073     }
1074     }
1075    
1076 dl 1.13 public void clear() {
1077     synchronized(l) {
1078     checkForComodification();
1079     l.removeRange(offset, offset+size);
1080     expectedArray = l.array;
1081     size = 0;
1082     }
1083     }
1084    
1085 tim 1.1 public E remove(int index) {
1086     synchronized(l) {
1087     rangeCheck(index);
1088     checkForComodification();
1089     E result = l.remove(index+offset);
1090 dl 1.12 expectedArray = l.array;
1091 tim 1.1 size--;
1092     return result;
1093     }
1094     }
1095    
1096     public Iterator<E> iterator() {
1097     synchronized(l) {
1098     checkForComodification();
1099 tim 1.8 return new COWSubListIterator<E>(l, 0, offset, size);
1100 tim 1.1 }
1101     }
1102    
1103     public ListIterator<E> listIterator(final int index) {
1104     synchronized(l) {
1105     checkForComodification();
1106     if (index<0 || index>size)
1107     throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
1108 tim 1.8 return new COWSubListIterator<E>(l, index, offset, size);
1109 tim 1.1 }
1110     }
1111    
1112 tim 1.7 public List<E> subList(int fromIndex, int toIndex) {
1113     synchronized(l) {
1114     checkForComodification();
1115     if (fromIndex<0 || toIndex>size)
1116     throw new IndexOutOfBoundsException();
1117     return new COWSubList<E>(l, fromIndex+offset, toIndex+offset);
1118 tim 1.1 }
1119 tim 1.7 }
1120 tim 1.1
1121 tim 1.7 }
1122 tim 1.1
1123    
1124 tim 1.7 private static class COWSubListIterator<E> implements ListIterator<E> {
1125     private final ListIterator<E> i;
1126     private final int index;
1127     private final int offset;
1128     private final int size;
1129     private COWSubListIterator(List<E> l, int index, int offset, int size) {
1130     this.index = index;
1131     this.offset = offset;
1132     this.size = size;
1133     i = l.listIterator(index+offset);
1134     }
1135 tim 1.1
1136 tim 1.7 public boolean hasNext() {
1137     return nextIndex() < size;
1138     }
1139 tim 1.1
1140 tim 1.7 public E next() {
1141     if (hasNext())
1142     return i.next();
1143     else
1144     throw new NoSuchElementException();
1145     }
1146 tim 1.1
1147 tim 1.7 public boolean hasPrevious() {
1148     return previousIndex() >= 0;
1149     }
1150 tim 1.1
1151 tim 1.7 public E previous() {
1152     if (hasPrevious())
1153     return i.previous();
1154     else
1155     throw new NoSuchElementException();
1156     }
1157 tim 1.1
1158 tim 1.7 public int nextIndex() {
1159     return i.nextIndex() - offset;
1160     }
1161 tim 1.1
1162 tim 1.7 public int previousIndex() {
1163     return i.previousIndex() - offset;
1164 tim 1.1 }
1165    
1166 tim 1.7 public void remove() {
1167     throw new UnsupportedOperationException();
1168     }
1169 tim 1.1
1170 tim 1.7 public void set(E o) {
1171     throw new UnsupportedOperationException();
1172 tim 1.1 }
1173    
1174 tim 1.7 public void add(E o) {
1175     throw new UnsupportedOperationException();
1176     }
1177 tim 1.1 }
1178    
1179     }