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