ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/CopyOnWriteArrayList.java
Revision: 1.1
Committed: Wed May 14 21:30:46 2003 UTC (21 years, 1 month ago) by tim
Branch: MAIN
Log Message:
Moved main source rooted at . to ./src/main
Moved test source rooted at ./etc/testcases to ./src/test

File Contents

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