ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/CopyOnWriteArrayList.java
Revision: 1.11
Committed: Mon Aug 25 19:27:58 2003 UTC (20 years, 9 months ago) by dl
Branch: MAIN
Changes since 1.10: +1 -0 lines
Log Message:
serialVersionUIDs

File Contents

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