1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/publicdomain/zero/1.0/
5  * Other contributors include Andrew Wright, Jeffrey Hayes,
6  * Pat Fisher, Mike Judd.
7  */
8 
9 package jsr166;
10 
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.Iterator;
16 import java.util.LinkedList;
17 import java.util.List;
18 import java.util.ListIterator;
19 import java.util.NoSuchElementException;
20 import java.util.concurrent.CopyOnWriteArrayList;
21 
22 import junit.framework.Test;
23 import junit.framework.TestSuite;
24 
25 public class CopyOnWriteArrayListTest extends JSR166TestCase {
26 
27     // android-note: Removed because the CTS runner does a bad job of
28     // retrying tests that have suite() declarations.
29     //
30     // public static void main(String[] args) {
31     //     main(suite(), args);
32     // }
33     // public static Test suite() {
34     //     return new TestSuite(CopyOnWriteArrayListTest.class);
35     // }
36 
populatedArray(int n)37     static CopyOnWriteArrayList<Integer> populatedArray(int n) {
38         CopyOnWriteArrayList<Integer> a = new CopyOnWriteArrayList<Integer>();
39         assertTrue(a.isEmpty());
40         for (int i = 0; i < n; i++)
41             a.add(i);
42         assertFalse(a.isEmpty());
43         assertEquals(n, a.size());
44         return a;
45     }
46 
populatedArray(Integer[] elements)47     static CopyOnWriteArrayList<Integer> populatedArray(Integer[] elements) {
48         CopyOnWriteArrayList<Integer> a = new CopyOnWriteArrayList<Integer>();
49         assertTrue(a.isEmpty());
50         for (int i = 0; i < elements.length; i++)
51             a.add(elements[i]);
52         assertFalse(a.isEmpty());
53         assertEquals(elements.length, a.size());
54         return a;
55     }
56 
57     /**
58      * a new list is empty
59      */
testConstructor()60     public void testConstructor() {
61         CopyOnWriteArrayList a = new CopyOnWriteArrayList();
62         assertTrue(a.isEmpty());
63     }
64 
65     /**
66      * new list contains all elements of initializing array
67      */
testConstructor2()68     public void testConstructor2() {
69         Integer[] ints = new Integer[SIZE];
70         for (int i = 0; i < SIZE - 1; ++i)
71             ints[i] = new Integer(i);
72         CopyOnWriteArrayList a = new CopyOnWriteArrayList(ints);
73         for (int i = 0; i < SIZE; ++i)
74             assertEquals(ints[i], a.get(i));
75     }
76 
77     /**
78      * new list contains all elements of initializing collection
79      */
testConstructor3()80     public void testConstructor3() {
81         Integer[] ints = new Integer[SIZE];
82         for (int i = 0; i < SIZE - 1; ++i)
83             ints[i] = new Integer(i);
84         CopyOnWriteArrayList a = new CopyOnWriteArrayList(Arrays.asList(ints));
85         for (int i = 0; i < SIZE; ++i)
86             assertEquals(ints[i], a.get(i));
87     }
88 
89     /**
90      * addAll adds each element from the given collection, including duplicates
91      */
testAddAll()92     public void testAddAll() {
93         CopyOnWriteArrayList full = populatedArray(3);
94         assertTrue(full.addAll(Arrays.asList(three, four, five)));
95         assertEquals(6, full.size());
96         assertTrue(full.addAll(Arrays.asList(three, four, five)));
97         assertEquals(9, full.size());
98     }
99 
100     /**
101      * addAllAbsent adds each element from the given collection that did not
102      * already exist in the List
103      */
testAddAllAbsent()104     public void testAddAllAbsent() {
105         CopyOnWriteArrayList full = populatedArray(3);
106         // "one" is duplicate and will not be added
107         assertEquals(2, full.addAllAbsent(Arrays.asList(three, four, one)));
108         assertEquals(5, full.size());
109         assertEquals(0, full.addAllAbsent(Arrays.asList(three, four, one)));
110         assertEquals(5, full.size());
111     }
112 
113     /**
114      * addIfAbsent will not add the element if it already exists in the list
115      */
testAddIfAbsent()116     public void testAddIfAbsent() {
117         CopyOnWriteArrayList full = populatedArray(SIZE);
118         full.addIfAbsent(one);
119         assertEquals(SIZE, full.size());
120     }
121 
122     /**
123      * addIfAbsent adds the element when it does not exist in the list
124      */
testAddIfAbsent2()125     public void testAddIfAbsent2() {
126         CopyOnWriteArrayList full = populatedArray(SIZE);
127         full.addIfAbsent(three);
128         assertTrue(full.contains(three));
129     }
130 
131     /**
132      * clear removes all elements from the list
133      */
testClear()134     public void testClear() {
135         CopyOnWriteArrayList full = populatedArray(SIZE);
136         full.clear();
137         assertEquals(0, full.size());
138     }
139 
140     /**
141      * Cloned list is equal
142      */
testClone()143     public void testClone() {
144         CopyOnWriteArrayList l1 = populatedArray(SIZE);
145         CopyOnWriteArrayList l2 = (CopyOnWriteArrayList)(l1.clone());
146         assertEquals(l1, l2);
147         l1.clear();
148         assertFalse(l1.equals(l2));
149     }
150 
151     /**
152      * contains is true for added elements
153      */
testContains()154     public void testContains() {
155         CopyOnWriteArrayList full = populatedArray(3);
156         assertTrue(full.contains(one));
157         assertFalse(full.contains(five));
158     }
159 
160     /**
161      * adding at an index places it in the indicated index
162      */
testAddIndex()163     public void testAddIndex() {
164         CopyOnWriteArrayList full = populatedArray(3);
165         full.add(0, m1);
166         assertEquals(4, full.size());
167         assertEquals(m1, full.get(0));
168         assertEquals(zero, full.get(1));
169 
170         full.add(2, m2);
171         assertEquals(5, full.size());
172         assertEquals(m2, full.get(2));
173         assertEquals(two, full.get(4));
174     }
175 
176     /**
177      * lists with same elements are equal and have same hashCode
178      */
testEquals()179     public void testEquals() {
180         CopyOnWriteArrayList a = populatedArray(3);
181         CopyOnWriteArrayList b = populatedArray(3);
182         assertTrue(a.equals(b));
183         assertTrue(b.equals(a));
184         assertTrue(a.containsAll(b));
185         assertTrue(b.containsAll(a));
186         assertEquals(a.hashCode(), b.hashCode());
187         a.add(m1);
188         assertFalse(a.equals(b));
189         assertFalse(b.equals(a));
190         assertTrue(a.containsAll(b));
191         assertFalse(b.containsAll(a));
192         b.add(m1);
193         assertTrue(a.equals(b));
194         assertTrue(b.equals(a));
195         assertTrue(a.containsAll(b));
196         assertTrue(b.containsAll(a));
197         assertEquals(a.hashCode(), b.hashCode());
198 
199         assertFalse(a.equals(null));
200     }
201 
202     /**
203      * containsAll returns true for collections with subset of elements
204      */
testContainsAll()205     public void testContainsAll() {
206         CopyOnWriteArrayList full = populatedArray(3);
207         assertTrue(full.containsAll(Arrays.asList()));
208         assertTrue(full.containsAll(Arrays.asList(one)));
209         assertTrue(full.containsAll(Arrays.asList(one, two)));
210         assertFalse(full.containsAll(Arrays.asList(one, two, six)));
211         assertFalse(full.containsAll(Arrays.asList(six)));
212 
213         try {
214             full.containsAll(null);
215             shouldThrow();
216         } catch (NullPointerException success) {}
217     }
218 
219     /**
220      * get returns the value at the given index
221      */
testGet()222     public void testGet() {
223         CopyOnWriteArrayList full = populatedArray(3);
224         assertEquals(0, full.get(0));
225     }
226 
227     /**
228      * indexOf gives the index for the given object
229      */
testIndexOf()230     public void testIndexOf() {
231         CopyOnWriteArrayList full = populatedArray(3);
232         assertEquals(1, full.indexOf(one));
233         assertEquals(-1, full.indexOf("puppies"));
234     }
235 
236     /**
237      * indexOf gives the index based on the given index
238      * at which to start searching
239      */
testIndexOf2()240     public void testIndexOf2() {
241         CopyOnWriteArrayList full = populatedArray(3);
242         assertEquals(1, full.indexOf(one, 0));
243         assertEquals(-1, full.indexOf(one, 2));
244     }
245 
246     /**
247      * isEmpty returns true when empty, else false
248      */
testIsEmpty()249     public void testIsEmpty() {
250         CopyOnWriteArrayList empty = new CopyOnWriteArrayList();
251         CopyOnWriteArrayList full = populatedArray(SIZE);
252         assertTrue(empty.isEmpty());
253         assertFalse(full.isEmpty());
254     }
255 
256     /**
257      * iterator() returns an iterator containing the elements of the
258      * list in insertion order
259      */
testIterator()260     public void testIterator() {
261         Collection empty = new CopyOnWriteArrayList();
262         assertFalse(empty.iterator().hasNext());
263         try {
264             empty.iterator().next();
265             shouldThrow();
266         } catch (NoSuchElementException success) {}
267 
268         Integer[] elements = new Integer[SIZE];
269         for (int i = 0; i < SIZE; i++)
270             elements[i] = i;
271         Collections.shuffle(Arrays.asList(elements));
272         Collection<Integer> full = populatedArray(elements);
273 
274         Iterator it = full.iterator();
275         for (int j = 0; j < SIZE; j++) {
276             assertTrue(it.hasNext());
277             assertEquals(elements[j], it.next());
278         }
279         assertIteratorExhausted(it);
280     }
281 
282     /**
283      * iterator of empty collection has no elements
284      */
testEmptyIterator()285     public void testEmptyIterator() {
286         Collection c = new CopyOnWriteArrayList();
287         assertIteratorExhausted(c.iterator());
288     }
289 
290     /**
291      * iterator.remove throws UnsupportedOperationException
292      */
testIteratorRemove()293     public void testIteratorRemove() {
294         CopyOnWriteArrayList full = populatedArray(SIZE);
295         Iterator it = full.iterator();
296         it.next();
297         try {
298             it.remove();
299             shouldThrow();
300         } catch (UnsupportedOperationException success) {}
301     }
302 
303     /**
304      * toString contains toString of elements
305      */
testToString()306     public void testToString() {
307         assertEquals("[]", new CopyOnWriteArrayList().toString());
308         CopyOnWriteArrayList full = populatedArray(3);
309         String s = full.toString();
310         for (int i = 0; i < 3; ++i)
311             assertTrue(s.contains(String.valueOf(i)));
312         assertEquals(new ArrayList(full).toString(),
313                      full.toString());
314     }
315 
316     /**
317      * lastIndexOf returns the index for the given object
318      */
testLastIndexOf1()319     public void testLastIndexOf1() {
320         CopyOnWriteArrayList full = populatedArray(3);
321         full.add(one);
322         full.add(three);
323         assertEquals(3, full.lastIndexOf(one));
324         assertEquals(-1, full.lastIndexOf(six));
325     }
326 
327     /**
328      * lastIndexOf returns the index from the given starting point
329      */
testLastIndexOf2()330     public void testLastIndexOf2() {
331         CopyOnWriteArrayList full = populatedArray(3);
332         full.add(one);
333         full.add(three);
334         assertEquals(3, full.lastIndexOf(one, 4));
335         assertEquals(-1, full.lastIndexOf(three, 3));
336     }
337 
338     /**
339      * listIterator traverses all elements
340      */
testListIterator1()341     public void testListIterator1() {
342         CopyOnWriteArrayList full = populatedArray(SIZE);
343         ListIterator i = full.listIterator();
344         int j;
345         for (j = 0; i.hasNext(); j++)
346             assertEquals(j, i.next());
347         assertEquals(SIZE, j);
348     }
349 
350     /**
351      * listIterator only returns those elements after the given index
352      */
testListIterator2()353     public void testListIterator2() {
354         CopyOnWriteArrayList full = populatedArray(3);
355         ListIterator i = full.listIterator(1);
356         int j;
357         for (j = 0; i.hasNext(); j++)
358             assertEquals(j + 1, i.next());
359         assertEquals(2, j);
360     }
361 
362     /**
363      * remove(int) removes and returns the object at the given index
364      */
testRemove_int()365     public void testRemove_int() {
366         int SIZE = 3;
367         for (int i = 0; i < SIZE; i++) {
368             CopyOnWriteArrayList full = populatedArray(SIZE);
369             assertEquals(i, full.remove(i));
370             assertEquals(SIZE - 1, full.size());
371             assertFalse(full.contains(new Integer(i)));
372         }
373     }
374 
375     /**
376      * remove(Object) removes the object if found and returns true
377      */
testRemove_Object()378     public void testRemove_Object() {
379         int SIZE = 3;
380         for (int i = 0; i < SIZE; i++) {
381             CopyOnWriteArrayList full = populatedArray(SIZE);
382             assertFalse(full.remove(new Integer(-42)));
383             assertTrue(full.remove(new Integer(i)));
384             assertEquals(SIZE - 1, full.size());
385             assertFalse(full.contains(new Integer(i)));
386         }
387         CopyOnWriteArrayList x = new CopyOnWriteArrayList(Arrays.asList(4, 5, 6));
388         assertTrue(x.remove(new Integer(6)));
389         assertEquals(x, Arrays.asList(4, 5));
390         assertTrue(x.remove(new Integer(4)));
391         assertEquals(x, Arrays.asList(5));
392         assertTrue(x.remove(new Integer(5)));
393         assertEquals(x, Arrays.asList());
394         assertFalse(x.remove(new Integer(5)));
395     }
396 
397     /**
398      * removeAll removes all elements from the given collection
399      */
testRemoveAll()400     public void testRemoveAll() {
401         CopyOnWriteArrayList full = populatedArray(3);
402         assertTrue(full.removeAll(Arrays.asList(one, two)));
403         assertEquals(1, full.size());
404         assertFalse(full.removeAll(Arrays.asList(one, two)));
405         assertEquals(1, full.size());
406     }
407 
408     /**
409      * set changes the element at the given index
410      */
testSet()411     public void testSet() {
412         CopyOnWriteArrayList full = populatedArray(3);
413         assertEquals(2, full.set(2, four));
414         assertEquals(4, full.get(2));
415     }
416 
417     /**
418      * size returns the number of elements
419      */
testSize()420     public void testSize() {
421         CopyOnWriteArrayList empty = new CopyOnWriteArrayList();
422         CopyOnWriteArrayList full = populatedArray(SIZE);
423         assertEquals(SIZE, full.size());
424         assertEquals(0, empty.size());
425     }
426 
427     /**
428      * toArray() returns an Object array containing all elements from
429      * the list in insertion order
430      */
testToArray()431     public void testToArray() {
432         Object[] a = new CopyOnWriteArrayList().toArray();
433         assertTrue(Arrays.equals(new Object[0], a));
434         assertSame(Object[].class, a.getClass());
435 
436         Integer[] elements = new Integer[SIZE];
437         for (int i = 0; i < SIZE; i++)
438             elements[i] = i;
439         Collections.shuffle(Arrays.asList(elements));
440         Collection<Integer> full = populatedArray(elements);
441 
442         assertTrue(Arrays.equals(elements, full.toArray()));
443         assertSame(Object[].class, full.toArray().getClass());
444     }
445 
446     /**
447      * toArray(Integer array) returns an Integer array containing all
448      * elements from the list in insertion order
449      */
testToArray2()450     public void testToArray2() {
451         Collection empty = new CopyOnWriteArrayList();
452         Integer[] a;
453 
454         a = new Integer[0];
455         assertSame(a, empty.toArray(a));
456 
457         a = new Integer[SIZE / 2];
458         Arrays.fill(a, 42);
459         assertSame(a, empty.toArray(a));
460         assertNull(a[0]);
461         for (int i = 1; i < a.length; i++)
462             assertEquals(42, (int) a[i]);
463 
464         Integer[] elements = new Integer[SIZE];
465         for (int i = 0; i < SIZE; i++)
466             elements[i] = i;
467         Collections.shuffle(Arrays.asList(elements));
468         Collection<Integer> full = populatedArray(elements);
469 
470         Arrays.fill(a, 42);
471         assertTrue(Arrays.equals(elements, full.toArray(a)));
472         for (int i = 0; i < a.length; i++)
473             assertEquals(42, (int) a[i]);
474         assertSame(Integer[].class, full.toArray(a).getClass());
475 
476         a = new Integer[SIZE];
477         Arrays.fill(a, 42);
478         assertSame(a, full.toArray(a));
479         assertTrue(Arrays.equals(elements, a));
480 
481         a = new Integer[2 * SIZE];
482         Arrays.fill(a, 42);
483         assertSame(a, full.toArray(a));
484         assertTrue(Arrays.equals(elements, Arrays.copyOf(a, SIZE)));
485         assertNull(a[SIZE]);
486         for (int i = SIZE + 1; i < a.length; i++)
487             assertEquals(42, (int) a[i]);
488     }
489 
490     /**
491      * sublists contains elements at indexes offset from their base
492      */
testSubList()493     public void testSubList() {
494         CopyOnWriteArrayList a = populatedArray(10);
495         assertTrue(a.subList(1,1).isEmpty());
496         for (int j = 0; j < 9; ++j) {
497             for (int i = j ; i < 10; ++i) {
498                 List b = a.subList(j,i);
499                 for (int k = j; k < i; ++k) {
500                     assertEquals(new Integer(k), b.get(k-j));
501                 }
502             }
503         }
504 
505         List s = a.subList(2, 5);
506         assertEquals(3, s.size());
507         s.set(2, m1);
508         assertEquals(a.get(4), m1);
509         s.clear();
510         assertEquals(7, a.size());
511     }
512 
513     // Exception tests
514 
515     /**
516      * toArray throws an ArrayStoreException when the given array
517      * can not store the objects inside the list
518      */
testToArray_ArrayStoreException()519     public void testToArray_ArrayStoreException() {
520         CopyOnWriteArrayList c = new CopyOnWriteArrayList();
521         c.add("zfasdfsdf");
522         c.add("asdadasd");
523         try {
524             c.toArray(new Long[5]);
525             shouldThrow();
526         } catch (ArrayStoreException success) {}
527     }
528 
529     /**
530      * get throws an IndexOutOfBoundsException on a negative index
531      */
testGet1_IndexOutOfBoundsException()532     public void testGet1_IndexOutOfBoundsException() {
533         CopyOnWriteArrayList c = populatedArray(5);
534         List[] lists = { c, c.subList(1, c.size() - 1) };
535         for (List list : lists) {
536             try {
537                 list.get(-1);
538                 shouldThrow();
539             } catch (IndexOutOfBoundsException success) {}
540         }
541     }
542 
543     /**
544      * get throws an IndexOutOfBoundsException on a too high index
545      */
testGet2_IndexOutOfBoundsException()546     public void testGet2_IndexOutOfBoundsException() {
547         CopyOnWriteArrayList c = populatedArray(5);
548         List[] lists = { c, c.subList(1, c.size() - 1) };
549         for (List list : lists) {
550             try {
551                 list.get(list.size());
552                 shouldThrow();
553             } catch (IndexOutOfBoundsException success) {}
554         }
555     }
556 
557     /**
558      * set throws an IndexOutOfBoundsException on a negative index
559      */
testSet1_IndexOutOfBoundsException()560     public void testSet1_IndexOutOfBoundsException() {
561         CopyOnWriteArrayList c = populatedArray(5);
562         List[] lists = { c, c.subList(1, c.size() - 1) };
563         for (List list : lists) {
564             try {
565                 list.set(-1, "qwerty");
566                 shouldThrow();
567             } catch (IndexOutOfBoundsException success) {}
568         }
569     }
570 
571     /**
572      * set throws an IndexOutOfBoundsException on a too high index
573      */
testSet2()574     public void testSet2() {
575         CopyOnWriteArrayList c = populatedArray(5);
576         List[] lists = { c, c.subList(1, c.size() - 1) };
577         for (List list : lists) {
578             try {
579                 list.set(list.size(), "qwerty");
580                 shouldThrow();
581             } catch (IndexOutOfBoundsException success) {}
582         }
583     }
584 
585     /**
586      * add throws an IndexOutOfBoundsException on a negative index
587      */
testAdd1_IndexOutOfBoundsException()588     public void testAdd1_IndexOutOfBoundsException() {
589         CopyOnWriteArrayList c = populatedArray(5);
590         List[] lists = { c, c.subList(1, c.size() - 1) };
591         for (List list : lists) {
592             try {
593                 list.add(-1, "qwerty");
594                 shouldThrow();
595             } catch (IndexOutOfBoundsException success) {}
596         }
597     }
598 
599     /**
600      * add throws an IndexOutOfBoundsException on a too high index
601      */
testAdd2_IndexOutOfBoundsException()602     public void testAdd2_IndexOutOfBoundsException() {
603         CopyOnWriteArrayList c = populatedArray(5);
604         List[] lists = { c, c.subList(1, c.size() - 1) };
605         for (List list : lists) {
606             try {
607                 list.add(list.size() + 1, "qwerty");
608                 shouldThrow();
609             } catch (IndexOutOfBoundsException success) {}
610         }
611     }
612 
613     /**
614      * remove throws an IndexOutOfBoundsException on a negative index
615      */
testRemove1_IndexOutOfBounds()616     public void testRemove1_IndexOutOfBounds() {
617         CopyOnWriteArrayList c = populatedArray(5);
618         List[] lists = { c, c.subList(1, c.size() - 1) };
619         for (List list : lists) {
620             try {
621                 list.remove(-1);
622                 shouldThrow();
623             } catch (IndexOutOfBoundsException success) {}
624         }
625     }
626 
627     /**
628      * remove throws an IndexOutOfBoundsException on a too high index
629      */
testRemove2_IndexOutOfBounds()630     public void testRemove2_IndexOutOfBounds() {
631         CopyOnWriteArrayList c = populatedArray(5);
632         List[] lists = { c, c.subList(1, c.size() - 1) };
633         for (List list : lists) {
634             try {
635                 list.remove(list.size());
636                 shouldThrow();
637             } catch (IndexOutOfBoundsException success) {}
638         }
639     }
640 
641     /**
642      * addAll throws an IndexOutOfBoundsException on a negative index
643      */
testAddAll1_IndexOutOfBoundsException()644     public void testAddAll1_IndexOutOfBoundsException() {
645         CopyOnWriteArrayList c = populatedArray(5);
646         List[] lists = { c, c.subList(1, c.size() - 1) };
647         for (List list : lists) {
648             try {
649                 list.addAll(-1, new LinkedList());
650                 shouldThrow();
651             } catch (IndexOutOfBoundsException success) {}
652         }
653     }
654 
655     /**
656      * addAll throws an IndexOutOfBoundsException on a too high index
657      */
testAddAll2_IndexOutOfBoundsException()658     public void testAddAll2_IndexOutOfBoundsException() {
659         CopyOnWriteArrayList c = populatedArray(5);
660         List[] lists = { c, c.subList(1, c.size() - 1) };
661         for (List list : lists) {
662             try {
663                 list.addAll(list.size() + 1, new LinkedList());
664                 shouldThrow();
665             } catch (IndexOutOfBoundsException success) {}
666         }
667     }
668 
669     /**
670      * listIterator throws an IndexOutOfBoundsException on a negative index
671      */
testListIterator1_IndexOutOfBoundsException()672     public void testListIterator1_IndexOutOfBoundsException() {
673         CopyOnWriteArrayList c = populatedArray(5);
674         List[] lists = { c, c.subList(1, c.size() - 1) };
675         for (List list : lists) {
676             try {
677                 list.listIterator(-1);
678                 shouldThrow();
679             } catch (IndexOutOfBoundsException success) {}
680         }
681     }
682 
683     /**
684      * listIterator throws an IndexOutOfBoundsException on a too high index
685      */
testListIterator2_IndexOutOfBoundsException()686     public void testListIterator2_IndexOutOfBoundsException() {
687         CopyOnWriteArrayList c = populatedArray(5);
688         List[] lists = { c, c.subList(1, c.size() - 1) };
689         for (List list : lists) {
690             try {
691                 list.listIterator(list.size() + 1);
692                 shouldThrow();
693             } catch (IndexOutOfBoundsException success) {}
694         }
695     }
696 
697     /**
698      * subList throws an IndexOutOfBoundsException on a negative index
699      */
testSubList1_IndexOutOfBoundsException()700     public void testSubList1_IndexOutOfBoundsException() {
701         CopyOnWriteArrayList c = populatedArray(5);
702         List[] lists = { c, c.subList(1, c.size() - 1) };
703         for (List list : lists) {
704             try {
705                 list.subList(-1, list.size());
706                 shouldThrow();
707             } catch (IndexOutOfBoundsException success) {}
708         }
709     }
710 
711     /**
712      * subList throws an IndexOutOfBoundsException on a too high index
713      */
testSubList2_IndexOutOfBoundsException()714     public void testSubList2_IndexOutOfBoundsException() {
715         CopyOnWriteArrayList c = populatedArray(5);
716         List[] lists = { c, c.subList(1, c.size() - 1) };
717         for (List list : lists) {
718             try {
719                 list.subList(0, list.size() + 1);
720                 shouldThrow();
721             } catch (IndexOutOfBoundsException success) {}
722         }
723     }
724 
725     /**
726      * subList throws IndexOutOfBoundsException when the second index
727      * is lower then the first
728      */
testSubList3_IndexOutOfBoundsException()729     public void testSubList3_IndexOutOfBoundsException() {
730         CopyOnWriteArrayList c = populatedArray(5);
731         List[] lists = { c, c.subList(1, c.size() - 1) };
732         for (List list : lists) {
733             try {
734                 list.subList(list.size() - 1, 1);
735                 shouldThrow();
736             } catch (IndexOutOfBoundsException success) {}
737         }
738     }
739 
740     /**
741      * a deserialized serialized list is equal
742      */
testSerialization()743     public void testSerialization() throws Exception {
744         List x = populatedArray(SIZE);
745         List y = serialClone(x);
746 
747         assertNotSame(x, y);
748         assertEquals(x.size(), y.size());
749         assertEquals(x.toString(), y.toString());
750         assertTrue(Arrays.equals(x.toArray(), y.toArray()));
751         assertEquals(x, y);
752         assertEquals(y, x);
753         while (!x.isEmpty()) {
754             assertFalse(y.isEmpty());
755             assertEquals(x.remove(0), y.remove(0));
756         }
757         assertTrue(y.isEmpty());
758     }
759 
760 }
761