1 /* 2 * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 6207984 6272521 6192552 6269713 6197726 6260652 5073546 4137464 27 * 4155650 4216399 4294891 6282555 6318622 6355327 6383475 6420753 28 * 6431845 4802633 6570566 6570575 6570631 6570924 6691185 6691215 29 * 4802647 7123424 8024709 30 * @summary Run many tests on many Collection and Map implementations 31 * @author Martin Buchholz 32 * @run main MOAT 33 * @key randomness 34 */ 35 36 /* Mother Of All (Collection) Tests 37 * 38 * Testing of collection classes is often spotty, because many tests 39 * need to be performed on many implementations, but the onus on 40 * writing the tests falls on the engineer introducing the new 41 * implementation. 42 * 43 * The idea of this mega-test is that: 44 * 45 * An engineer adding a new collection implementation could simply add 46 * their new implementation to a list of implementations in this 47 * test's main method. Any general purpose Collection<Integer> or 48 * Map<Integer,Integer> class is appropriate. 49 * 50 * An engineer fixing a regression could add their regression test here and 51 * simultaneously test all other implementations. 52 */ 53 54 import java.io.*; 55 import java.util.*; 56 import java.util.concurrent.*; 57 import static java.util.Collections.*; 58 import java.lang.reflect.*; 59 60 public class MOAT { 61 public static void realMain(String[] args) { 62 63 testCollection(new NewAbstractCollection<Integer>()); 64 testCollection(new NewAbstractSet<Integer>()); 65 testCollection(new LinkedHashSet<Integer>()); 66 testCollection(new HashSet<Integer>()); 67 testCollection(new Vector<Integer>()); 68 testCollection(new Vector<Integer>().subList(0,0)); 69 testCollection(new ArrayDeque<Integer>()); 70 testCollection(new ArrayList<Integer>()); 71 testCollection(new ArrayList<Integer>().subList(0,0)); 72 testCollection(new LinkedList<Integer>()); 73 testCollection(new LinkedList<Integer>().subList(0,0)); 74 testCollection(new TreeSet<Integer>()); 75 testCollection(Collections.checkedList(new ArrayList<Integer>(), Integer.class)); 76 testCollection(Collections.synchronizedList(new ArrayList<Integer>())); 77 testCollection(Collections.checkedSet(new HashSet<Integer>(), Integer.class)); 78 testCollection(Collections.checkedSortedSet(new TreeSet<Integer>(), Integer.class)); 79 testCollection(Collections.checkedNavigableSet(new TreeSet<Integer>(), Integer.class)); 80 testCollection(Collections.synchronizedSet(new HashSet<Integer>())); 81 testCollection(Collections.synchronizedSortedSet(new TreeSet<Integer>())); 82 testCollection(Collections.synchronizedNavigableSet(new TreeSet<Integer>())); 83 84 testCollection(new CopyOnWriteArrayList<Integer>()); 85 testCollection(new CopyOnWriteArrayList<Integer>().subList(0,0)); 86 testCollection(new CopyOnWriteArraySet<Integer>()); 87 testCollection(new PriorityQueue<Integer>()); 88 testCollection(new PriorityBlockingQueue<Integer>()); 89 testCollection(new ArrayBlockingQueue<Integer>(20)); 90 testCollection(new LinkedBlockingQueue<Integer>(20)); 91 testCollection(new LinkedBlockingDeque<Integer>(20)); 92 testCollection(new ConcurrentLinkedDeque<Integer>()); 93 testCollection(new ConcurrentLinkedQueue<Integer>()); 94 testCollection(new LinkedTransferQueue<Integer>()); 95 testCollection(new ConcurrentSkipListSet<Integer>()); 96 testCollection(Arrays.asList(new Integer(42))); 97 testCollection(Arrays.asList(1,2,3)); 98 testCollection(nCopies(25,1)); 99 testImmutableList(nCopies(25,1)); 100 testImmutableList(unmodifiableList(Arrays.asList(1,2,3))); 101 102 testMap(new HashMap<Integer,Integer>()); 103 testMap(new LinkedHashMap<Integer,Integer>()); 104 testMap(new WeakHashMap<Integer,Integer>()); 105 testMap(new IdentityHashMap<Integer,Integer>()); 106 testMap(new TreeMap<Integer,Integer>()); 107 testMap(new Hashtable<Integer,Integer>()); 108 testMap(new ConcurrentHashMap<Integer,Integer>(10, 0.5f)); 109 testMap(new ConcurrentSkipListMap<Integer,Integer>()); 110 testMap(Collections.checkedMap(new HashMap<Integer,Integer>(), Integer.class, Integer.class)); 111 testMap(Collections.checkedSortedMap(new TreeMap<Integer,Integer>(), Integer.class, Integer.class)); 112 testMap(Collections.checkedNavigableMap(new TreeMap<Integer,Integer>(), Integer.class, Integer.class)); 113 testMap(Collections.synchronizedMap(new HashMap<Integer,Integer>())); 114 testMap(Collections.synchronizedSortedMap(new TreeMap<Integer,Integer>())); 115 testMap(Collections.synchronizedNavigableMap(new TreeMap<Integer,Integer>())); 116 117 // Empty collections 118 final List<Integer> emptyArray = Arrays.asList(new Integer[]{}); 119 testCollection(emptyArray); 120 testEmptyList(emptyArray); 121 THROWS(IndexOutOfBoundsException.class, () -> emptyArray.set(0,1)); 122 THROWS(UnsupportedOperationException.class, () -> emptyArray.add(0,1)); 123 124 List<Integer> noOne = nCopies(0,1); 125 testCollection(noOne); 126 testEmptyList(noOne); 127 testImmutableList(noOne); 128 129 Set<Integer> emptySet = emptySet(); 130 testCollection(emptySet); 131 testEmptySet(emptySet); 132 testEmptySet(EMPTY_SET); 133 testEmptySet(Collections.emptySet()); 134 testEmptySet(Collections.emptySortedSet()); 135 testEmptySet(Collections.emptyNavigableSet()); 136 testImmutableSet(emptySet); 137 138 List<Integer> emptyList = emptyList(); 139 testCollection(emptyList); 140 testEmptyList(emptyList); 141 testEmptyList(EMPTY_LIST); 142 testEmptyList(Collections.emptyList()); 143 testImmutableList(emptyList); 144 145 Map<Integer,Integer> emptyMap = emptyMap(); 146 testMap(emptyMap); 147 testEmptyMap(emptyMap); 148 testEmptyMap(EMPTY_MAP); 149 testEmptyMap(Collections.emptyMap()); 150 testEmptyMap(Collections.emptySortedMap()); 151 testEmptyMap(Collections.emptyNavigableMap()); 152 testImmutableMap(emptyMap); 153 testImmutableMap(Collections.emptyMap()); 154 testImmutableMap(Collections.emptySortedMap()); 155 testImmutableMap(Collections.emptyNavigableMap()); 156 157 // Singleton collections 158 Set<Integer> singletonSet = singleton(1); 159 equal(singletonSet.size(), 1); 160 testCollection(singletonSet); 161 testImmutableSet(singletonSet); 162 163 List<Integer> singletonList = singletonList(1); 164 equal(singletonList.size(), 1); 165 testCollection(singletonList); 166 testImmutableList(singletonList); 167 testImmutableList(singletonList.subList(0,1)); 168 testImmutableList(singletonList.subList(0,1).subList(0,1)); 169 testEmptyList(singletonList.subList(0,0)); 170 testEmptyList(singletonList.subList(0,0).subList(0,0)); 171 172 Map<Integer,Integer> singletonMap = singletonMap(1,2); 173 equal(singletonMap.size(), 1); 174 testMap(singletonMap); 175 testImmutableMap(singletonMap); 176 } 177 178 private static void checkContainsSelf(Collection<Integer> c) { 179 check(c.containsAll(c)); 180 check(c.containsAll(Arrays.asList(c.toArray()))); 181 check(c.containsAll(Arrays.asList(c.toArray(new Integer[0])))); 182 } 183 184 private static void checkContainsEmpty(Collection<Integer> c) { 185 check(c.containsAll(new ArrayList<Integer>())); 186 } 187 188 private static <T> void testEmptyCollection(Collection<T> c) { 189 check(c.isEmpty()); 190 equal(c.size(), 0); 191 equal(c.toString(),"[]"); 192 equal(c.toArray().length, 0); 193 equal(c.toArray(new Object[0]).length, 0); 194 check(c.toArray(new Object[]{42})[0] == null); 195 196 Object[] a = new Object[1]; a[0] = Boolean.TRUE; 197 equal(c.toArray(a), a); 198 equal(a[0], null); 199 testEmptyIterator(c.iterator()); 200 } 201 202 static <T> void testEmptyIterator(final Iterator<T> it) { 203 if (rnd.nextBoolean()) 204 check(! it.hasNext()); 205 206 THROWS(NoSuchElementException.class, () -> it.next()); 207 208 try { it.remove(); } 209 catch (IllegalStateException ignored) { pass(); } 210 catch (UnsupportedOperationException ignored) { pass(); } 211 catch (Throwable t) { unexpected(t); } 212 213 if (rnd.nextBoolean()) 214 check(! it.hasNext()); 215 } 216 217 private static void testEmptyList(List<?> c) { 218 testEmptyCollection(c); 219 equal(c.hashCode(), 1); 220 equal2(c, Collections.<Integer>emptyList()); 221 } 222 223 private static <T> void testEmptySet(Set<T> c) { 224 testEmptyCollection(c); 225 equal(c.hashCode(), 0); 226 equal2(c, Collections.<Integer>emptySet()); 227 if (c instanceof NavigableSet<?>) 228 testEmptyIterator(((NavigableSet<T>)c).descendingIterator()); 229 } 230 231 private static void testImmutableCollection(final Collection<Integer> c) { 232 THROWS(UnsupportedOperationException.class, 233 () -> c.add(99), 234 () -> c.addAll(singleton(99))); 235 if (! c.isEmpty()) { 236 final Integer first = c.iterator().next(); 237 THROWS(UnsupportedOperationException.class, 238 () -> c.clear(), 239 () -> c.remove(first), 240 () -> c.removeAll(singleton(first)), 241 () -> c.retainAll(emptyList())); 242 } 243 } 244 245 private static void testImmutableSet(final Set<Integer> c) { 246 testImmutableCollection(c); 247 } 248 249 private static void testImmutableList(final List<Integer> c) { 250 testList(c); 251 testImmutableCollection(c); 252 THROWS(UnsupportedOperationException.class, 253 () -> c.set(0,42), 254 () -> c.add(0,42), 255 () -> c.addAll(0,singleton(86))); 256 if (! c.isEmpty()) 257 THROWS(UnsupportedOperationException.class, 258 () -> { Iterator<Integer> it = c.iterator(); 259 it.next(); 260 it.remove(); }, 261 () -> { ListIterator<Integer> it = c.listIterator(); 262 it.next(); 263 it.remove(); }); 264 } 265 266 private static void clear(Collection<Integer> c) { 267 try { c.clear(); } 268 catch (Throwable t) { unexpected(t); } 269 testEmptyCollection(c); 270 } 271 272 private static <K,V> void testEmptyMap(final Map<K,V> m) { 273 check(m.isEmpty()); 274 equal(m.size(), 0); 275 equal(m.toString(),"{}"); 276 testEmptySet(m.keySet()); 277 testEmptySet(m.entrySet()); 278 testEmptyCollection(m.values()); 279 280 try { check(! m.containsValue(null)); } 281 catch (NullPointerException ignored) { /* OK */ } 282 try { check(! m.containsKey(null)); } 283 catch (NullPointerException ignored) { /* OK */ } 284 check(! m.containsValue(1)); 285 check(! m.containsKey(1)); 286 } 287 288 private static void testImmutableMap(final Map<Integer,Integer> m) { 289 THROWS(UnsupportedOperationException.class, 290 () -> m.put(1,1), 291 () -> m.putAll(singletonMap(1,1))); 292 if (! m.isEmpty()) { 293 final Integer first = m.keySet().iterator().next(); 294 THROWS(UnsupportedOperationException.class, 295 () -> m.remove(first), 296 () -> m.clear()); 297 final Map.Entry<Integer,Integer> me 298 = m.entrySet().iterator().next(); 299 Integer key = me.getKey(); 300 Integer val = me.getValue(); 301 THROWS(UnsupportedOperationException.class, 302 () -> me.setValue(3)); 303 equal(key, me.getKey()); 304 equal(val, me.getValue()); 305 } 306 testImmutableSet(m.keySet()); 307 testImmutableCollection(m.values()); 308 //testImmutableSet(m.entrySet()); 309 } 310 311 private static void clear(Map<?,?> m) { 312 try { m.clear(); } 313 catch (Throwable t) { unexpected(t); } 314 testEmptyMap(m); 315 } 316 317 private static void oneElement(Collection<Integer> c) { 318 clear(c); 319 try { 320 check(c.add(-42)); 321 equal(c.toString(), "[-42]"); 322 if (c instanceof Set) check(! c.add(-42)); 323 } catch (Throwable t) { unexpected(t); } 324 check(! c.isEmpty()); check(c.size() == 1); 325 } 326 327 private static boolean supportsAdd(Collection<Integer> c) { 328 try { check(c.add(778347983)); } 329 catch (UnsupportedOperationException t) { return false; } 330 catch (Throwable t) { unexpected(t); } 331 332 try { 333 check(c.contains(778347983)); 334 check(c.remove(778347983)); 335 } catch (Throwable t) { unexpected(t); } 336 return true; 337 } 338 339 private static boolean supportsRemove(Collection<Integer> c) { 340 try { check(! c.remove(19134032)); } 341 catch (UnsupportedOperationException t) { return false; } 342 catch (Throwable t) { unexpected(t); } 343 return true; 344 } 345 346 private static void checkFunctionalInvariants(Collection<Integer> c) { 347 try { 348 checkContainsSelf(c); 349 checkContainsEmpty(c); 350 check(c.size() != 0 ^ c.isEmpty()); 351 352 { 353 int size = 0; 354 for (Integer i : c) size++; 355 check(c.size() == size); 356 } 357 358 check(c.toArray().length == c.size()); 359 check(c.toArray().getClass() == Object[].class 360 || 361 // !!!! 362 // 6260652: (coll) Arrays.asList(x).toArray().getClass() 363 // should be Object[].class 364 (c.getClass().getName().equals("java.util.Arrays$ArrayList")) 365 ); 366 for (int size : new int[]{0,1,c.size(), c.size()+1}) { 367 Integer[] a = c.toArray(new Integer[size]); 368 check((size > c.size()) || a.length == c.size()); 369 int i = 0; for (Integer j : c) check(a[i++] == j); 370 check((size <= c.size()) || (a[c.size()] == null)); 371 check(a.getClass() == Integer[].class); 372 } 373 374 check(c.equals(c)); 375 if (c instanceof Serializable) { 376 //System.out.printf("Serializing %s%n", c.getClass().getName()); 377 try { 378 Object clone = serialClone(c); 379 equal(c instanceof Serializable, 380 clone instanceof Serializable); 381 equal(c instanceof RandomAccess, 382 clone instanceof RandomAccess); 383 if ((c instanceof List) || (c instanceof Set)) 384 equal(c, clone); 385 else 386 equal(new HashSet<Integer>(c), 387 new HashSet<Integer>(serialClone(c))); 388 } catch (Error xxx) { 389 if (! (xxx.getCause() instanceof NotSerializableException)) 390 throw xxx; 391 } 392 } 393 } 394 catch (Throwable t) { unexpected(t); } 395 } 396 397 //---------------------------------------------------------------- 398 // If add(null) succeeds, contains(null) & remove(null) should succeed 399 //---------------------------------------------------------------- 400 private static void testNullElement(Collection<Integer> c) { 401 402 try { 403 check(c.add(null)); 404 if (c.size() == 1) 405 equal(c.toString(), "[null]"); 406 try { 407 checkFunctionalInvariants(c); 408 check(c.contains(null)); 409 check(c.remove(null)); 410 } 411 catch (Throwable t) { unexpected(t); } 412 } 413 catch (NullPointerException e) { /* OK */ } 414 catch (Throwable t) { unexpected(t); } 415 } 416 417 418 //---------------------------------------------------------------- 419 // If add("x") succeeds, contains("x") & remove("x") should succeed 420 //---------------------------------------------------------------- 421 @SuppressWarnings("unchecked") 422 private static void testStringElement(Collection<Integer> c) { 423 Collection x = (Collection)c; // Make type-unsafe 424 try { 425 check(x.add("x")); 426 try { 427 check(x.contains("x")); 428 check(x.remove("x")); 429 } catch (Throwable t) { unexpected(t); } 430 } 431 catch (ClassCastException e) { /* OK */ } 432 catch (Throwable t) { unexpected(t); } 433 } 434 435 private static void testConcurrentCollection(Collection<Integer> c) { 436 try { 437 c.add(1); 438 Iterator<Integer> it = c.iterator(); 439 check(it.hasNext()); 440 clear(c); 441 check(it.next() instanceof Integer); // No CME 442 check(c.isEmpty()); 443 } 444 catch (Throwable t) { unexpected(t); } 445 } 446 447 private static void testQueue(Queue<Integer> q) { 448 q.clear(); 449 for (int i = 0; i < 5; i++) { 450 testQueueAddRemove(q, null); 451 testQueueAddRemove(q, 537); 452 q.add(i); 453 } 454 equal(q.size(), 5); 455 checkFunctionalInvariants(q); 456 q.poll(); 457 equal(q.size(), 4); 458 checkFunctionalInvariants(q); 459 if ((q instanceof LinkedBlockingQueue) || 460 (q instanceof LinkedBlockingDeque) || 461 (q instanceof ConcurrentLinkedDeque) || 462 (q instanceof ConcurrentLinkedQueue)) { 463 testQueueIteratorRemove(q); 464 } 465 } 466 467 private static void testQueueAddRemove(final Queue<Integer> q, 468 final Integer e) { 469 final List<Integer> originalContents = new ArrayList<Integer>(q); 470 final boolean isEmpty = q.isEmpty(); 471 final boolean isList = (q instanceof List); 472 final List asList = isList ? (List) q : null; 473 check(!q.contains(e)); 474 try { 475 q.add(e); 476 } catch (NullPointerException npe) { 477 check(e == null); 478 return; // Null elements not supported 479 } 480 check(q.contains(e)); 481 check(q.remove(e)); 482 check(!q.contains(e)); 483 equal(new ArrayList<Integer>(q), originalContents); 484 485 if (q instanceof Deque<?>) { 486 final Deque<Integer> deq = (Deque<Integer>) q; 487 final List<Integer> singleton = Collections.singletonList(e); 488 489 // insert, query, remove element at head 490 if (isEmpty) { 491 THROWS(NoSuchElementException.class, 492 () -> deq.getFirst(), 493 () -> deq.element(), 494 () -> deq.iterator().next()); 495 check(deq.peekFirst() == null); 496 check(deq.peek() == null); 497 } else { 498 check(deq.getFirst() != e); 499 check(deq.element() != e); 500 check(deq.iterator().next() != e); 501 check(deq.peekFirst() != e); 502 check(deq.peek() != e); 503 } 504 check(!deq.contains(e)); 505 check(!deq.removeFirstOccurrence(e)); 506 check(!deq.removeLastOccurrence(e)); 507 if (isList) { 508 check(asList.indexOf(e) == -1); 509 check(asList.lastIndexOf(e) == -1); 510 } 511 switch (rnd.nextInt(isList ? 4 : 3)) { 512 case 0: deq.addFirst(e); break; 513 case 1: check(deq.offerFirst(e)); break; 514 case 2: deq.push(e); break; 515 case 3: asList.add(0, e); break; 516 default: throw new AssertionError(); 517 } 518 check(deq.peekFirst() == e); 519 check(deq.getFirst() == e); 520 check(deq.element() == e); 521 check(deq.peek() == e); 522 check(deq.iterator().next() == e); 523 check(deq.contains(e)); 524 if (isList) { 525 check(asList.get(0) == e); 526 check(asList.indexOf(e) == 0); 527 check(asList.lastIndexOf(e) == 0); 528 check(asList.subList(0, 1).equals(singleton)); 529 } 530 switch (rnd.nextInt(isList ? 11 : 9)) { 531 case 0: check(deq.pollFirst() == e); break; 532 case 1: check(deq.removeFirst() == e); break; 533 case 2: check(deq.remove() == e); break; 534 case 3: check(deq.pop() == e); break; 535 case 4: check(deq.removeFirstOccurrence(e)); break; 536 case 5: check(deq.removeLastOccurrence(e)); break; 537 case 6: check(deq.remove(e)); break; 538 case 7: check(deq.removeAll(singleton)); break; 539 case 8: Iterator it = deq.iterator(); it.next(); it.remove(); break; 540 case 9: asList.remove(0); break; 541 case 10: asList.subList(0, 1).clear(); break; 542 default: throw new AssertionError(); 543 } 544 if (isEmpty) { 545 THROWS(NoSuchElementException.class, 546 () -> deq.getFirst(), 547 () -> deq.element(), 548 () -> deq.iterator().next()); 549 check(deq.peekFirst() == null); 550 check(deq.peek() == null); 551 } else { 552 check(deq.getFirst() != e); 553 check(deq.element() != e); 554 check(deq.iterator().next() != e); 555 check(deq.peekFirst() != e); 556 check(deq.peek() != e); 557 } 558 check(!deq.contains(e)); 559 check(!deq.removeFirstOccurrence(e)); 560 check(!deq.removeLastOccurrence(e)); 561 if (isList) { 562 check(isEmpty || asList.get(0) != e); 563 check(asList.indexOf(e) == -1); 564 check(asList.lastIndexOf(e) == -1); 565 } 566 equal(new ArrayList<Integer>(deq), originalContents); 567 568 // insert, query, remove element at tail 569 if (isEmpty) { 570 check(deq.peekLast() == null); 571 THROWS(NoSuchElementException.class, () -> deq.getLast()); 572 } else { 573 check(deq.peekLast() != e); 574 check(deq.getLast() != e); 575 } 576 switch (rnd.nextInt(isList ? 6 : 4)) { 577 case 0: deq.addLast(e); break; 578 case 1: check(deq.offerLast(e)); break; 579 case 2: check(deq.add(e)); break; 580 case 3: deq.addAll(singleton); break; 581 case 4: asList.addAll(deq.size(), singleton); break; 582 case 5: asList.add(deq.size(), e); break; 583 default: throw new AssertionError(); 584 } 585 check(deq.peekLast() == e); 586 check(deq.getLast() == e); 587 check(deq.contains(e)); 588 if (isList) { 589 ListIterator it = asList.listIterator(asList.size()); 590 check(it.previous() == e); 591 check(asList.get(asList.size() - 1) == e); 592 check(asList.indexOf(e) == asList.size() - 1); 593 check(asList.lastIndexOf(e) == asList.size() - 1); 594 int size = asList.size(); 595 check(asList.subList(size - 1, size).equals(singleton)); 596 } 597 switch (rnd.nextInt(isList ? 8 : 6)) { 598 case 0: check(deq.pollLast() == e); break; 599 case 1: check(deq.removeLast() == e); break; 600 case 2: check(deq.removeFirstOccurrence(e)); break; 601 case 3: check(deq.removeLastOccurrence(e)); break; 602 case 4: check(deq.remove(e)); break; 603 case 5: check(deq.removeAll(singleton)); break; 604 case 6: asList.remove(asList.size() - 1); break; 605 case 7: 606 ListIterator it = asList.listIterator(asList.size()); 607 it.previous(); 608 it.remove(); 609 break; 610 default: throw new AssertionError(); 611 } 612 if (isEmpty) { 613 check(deq.peekLast() == null); 614 THROWS(NoSuchElementException.class, () -> deq.getLast()); 615 } else { 616 check(deq.peekLast() != e); 617 check(deq.getLast() != e); 618 } 619 check(!deq.contains(e)); 620 equal(new ArrayList<Integer>(deq), originalContents); 621 622 // Test operations on empty deque 623 switch (rnd.nextInt(isList ? 4 : 2)) { 624 case 0: deq.clear(); break; 625 case 1: 626 Iterator it = deq.iterator(); 627 while (it.hasNext()) { 628 it.next(); 629 it.remove(); 630 } 631 break; 632 case 2: asList.subList(0, asList.size()).clear(); break; 633 case 3: 634 ListIterator lit = asList.listIterator(asList.size()); 635 while (lit.hasPrevious()) { 636 lit.previous(); 637 lit.remove(); 638 } 639 break; 640 default: throw new AssertionError(); 641 } 642 testEmptyCollection(deq); 643 check(!deq.iterator().hasNext()); 644 if (isList) { 645 check(!asList.listIterator().hasPrevious()); 646 THROWS(NoSuchElementException.class, 647 () -> asList.listIterator().previous()); 648 } 649 THROWS(NoSuchElementException.class, 650 () -> deq.iterator().next(), 651 () -> deq.element(), 652 () -> deq.getFirst(), 653 () -> deq.getLast(), 654 () -> deq.pop(), 655 () -> deq.remove(), 656 () -> deq.removeFirst(), 657 () -> deq.removeLast()); 658 659 check(deq.poll() == null); 660 check(deq.pollFirst() == null); 661 check(deq.pollLast() == null); 662 check(deq.peek() == null); 663 check(deq.peekFirst() == null); 664 check(deq.peekLast() == null); 665 check(!deq.removeFirstOccurrence(e)); 666 check(!deq.removeLastOccurrence(e)); 667 668 check(deq.addAll(originalContents) == !isEmpty); 669 equal(new ArrayList<Integer>(deq), originalContents); 670 check(!deq.addAll(Collections.<Integer>emptyList())); 671 equal(new ArrayList<Integer>(deq), originalContents); 672 } 673 } 674 675 private static void testQueueIteratorRemove(Queue<Integer> q) { 676 System.err.printf("testQueueIteratorRemove %s%n", 677 q.getClass().getSimpleName()); 678 q.clear(); 679 for (int i = 0; i < 5; i++) 680 q.add(i); 681 Iterator<Integer> it = q.iterator(); 682 check(it.hasNext()); 683 for (int i = 3; i >= 0; i--) 684 q.remove(i); 685 equal(it.next(), 0); 686 equal(it.next(), 4); 687 688 q.clear(); 689 for (int i = 0; i < 5; i++) 690 q.add(i); 691 it = q.iterator(); 692 equal(it.next(), 0); 693 check(it.hasNext()); 694 for (int i = 1; i < 4; i++) 695 q.remove(i); 696 equal(it.next(), 1); 697 equal(it.next(), 4); 698 } 699 700 private static void testList(final List<Integer> l) { 701 //---------------------------------------------------------------- 702 // 4802633: (coll) AbstractList.addAll(-1,emptyCollection) 703 // doesn't throw IndexOutOfBoundsException 704 //---------------------------------------------------------------- 705 try { 706 l.addAll(-1, Collections.<Integer>emptyList()); 707 fail("Expected IndexOutOfBoundsException not thrown"); 708 } 709 catch (UnsupportedOperationException ignored) {/* OK */} 710 catch (IndexOutOfBoundsException ignored) {/* OK */} 711 catch (Throwable t) { unexpected(t); } 712 713 // equal(l instanceof Serializable, 714 // l.subList(0,0) instanceof Serializable); 715 if (l.subList(0,0) instanceof Serializable) 716 check(l instanceof Serializable); 717 718 equal(l instanceof RandomAccess, 719 l.subList(0,0) instanceof RandomAccess); 720 721 l.iterator(); 722 l.listIterator(); 723 l.listIterator(0); 724 l.listIterator(l.size()); 725 THROWS(IndexOutOfBoundsException.class, 726 () -> l.listIterator(-1), 727 () -> l.listIterator(l.size() + 1)); 728 729 if (l instanceof AbstractList) { 730 try { 731 int size = l.size(); 732 AbstractList<Integer> abList = (AbstractList<Integer>) l; 733 Method m = AbstractList.class.getDeclaredMethod("removeRange", new Class[] { int.class, int.class }); 734 m.setAccessible(true); 735 m.invoke(abList, new Object[] { 0, 0 }); 736 m.invoke(abList, new Object[] { size, size }); 737 equal(size, l.size()); 738 } 739 catch (UnsupportedOperationException ignored) {/* OK */} 740 catch (Throwable t) { unexpected(t); } 741 } 742 } 743 744 private static void testCollection(Collection<Integer> c) { 745 try { testCollection1(c); } 746 catch (Throwable t) { unexpected(t); } 747 } 748 749 private static void testCollection1(Collection<Integer> c) { 750 751 System.out.println("\n==> " + c.getClass().getName()); 752 753 checkFunctionalInvariants(c); 754 755 if (! supportsAdd(c)) return; 756 //System.out.println("add() supported"); 757 758 if (c instanceof NavigableSet) { 759 System.out.println("NavigableSet tests..."); 760 761 NavigableSet<Integer> ns = (NavigableSet<Integer>)c; 762 testNavigableSet(ns); 763 testNavigableSet(ns.headSet(6, false)); 764 testNavigableSet(ns.headSet(5, true)); 765 testNavigableSet(ns.tailSet(0, false)); 766 testNavigableSet(ns.tailSet(1, true)); 767 testNavigableSet(ns.subSet(0, false, 5, true)); 768 testNavigableSet(ns.subSet(1, true, 6, false)); 769 } 770 771 if (c instanceof Queue) 772 testQueue((Queue<Integer>)c); 773 774 if (c instanceof List) 775 testList((List<Integer>)c); 776 777 check(supportsRemove(c)); 778 779 try { 780 oneElement(c); 781 checkFunctionalInvariants(c); 782 } 783 catch (Throwable t) { unexpected(t); } 784 785 clear(c); testNullElement(c); 786 oneElement(c); testNullElement(c); 787 788 clear(c); testStringElement(c); 789 oneElement(c); testStringElement(c); 790 791 if (c.getClass().getName().matches(".*concurrent.*")) 792 testConcurrentCollection(c); 793 794 //---------------------------------------------------------------- 795 // The "all" operations should throw NPE when passed null 796 //---------------------------------------------------------------- 797 { 798 clear(c); 799 try { 800 c.removeAll(null); 801 fail("Expected NullPointerException"); 802 } 803 catch (NullPointerException e) { pass(); } 804 catch (Throwable t) { unexpected(t); } 805 806 oneElement(c); 807 try { 808 c.removeAll(null); 809 fail("Expected NullPointerException"); 810 } 811 catch (NullPointerException e) { pass(); } 812 catch (Throwable t) { unexpected(t); } 813 814 clear(c); 815 try { 816 c.retainAll(null); 817 fail("Expected NullPointerException"); 818 } 819 catch (NullPointerException e) { pass(); } 820 catch (Throwable t) { unexpected(t); } 821 822 oneElement(c); 823 try { 824 c.retainAll(null); 825 fail("Expected NullPointerException"); 826 } 827 catch (NullPointerException e) { pass(); } 828 catch (Throwable t) { unexpected(t); } 829 830 oneElement(c); 831 try { 832 c.addAll(null); 833 fail("Expected NullPointerException"); 834 } 835 catch (NullPointerException e) { pass(); } 836 catch (Throwable t) { unexpected(t); } 837 838 oneElement(c); 839 try { 840 c.containsAll(null); 841 fail("Expected NullPointerException"); 842 } 843 catch (NullPointerException e) { pass(); } 844 catch (Throwable t) { unexpected(t); } 845 } 846 } 847 848 //---------------------------------------------------------------- 849 // Map 850 //---------------------------------------------------------------- 851 private static void checkFunctionalInvariants(Map<Integer,Integer> m) { 852 check(m.keySet().size() == m.entrySet().size()); 853 check(m.keySet().size() == m.size()); 854 checkFunctionalInvariants(m.keySet()); 855 checkFunctionalInvariants(m.values()); 856 check(m.size() != 0 ^ m.isEmpty()); 857 } 858 859 private static void testMap(Map<Integer,Integer> m) { 860 System.out.println("\n==> " + m.getClass().getName()); 861 862 if (m instanceof ConcurrentMap) 863 testConcurrentMap((ConcurrentMap<Integer,Integer>) m); 864 865 if (m instanceof NavigableMap) { 866 System.out.println("NavigableMap tests..."); 867 868 NavigableMap<Integer,Integer> nm = 869 (NavigableMap<Integer,Integer>) m; 870 testNavigableMapRemovers(nm); 871 testNavigableMap(nm); 872 testNavigableMap(nm.headMap(6, false)); 873 testNavigableMap(nm.headMap(5, true)); 874 testNavigableMap(nm.tailMap(0, false)); 875 testNavigableMap(nm.tailMap(1, true)); 876 testNavigableMap(nm.subMap(1, true, 6, false)); 877 testNavigableMap(nm.subMap(0, false, 5, true)); 878 } 879 880 checkFunctionalInvariants(m); 881 882 if (supportsClear(m)) { 883 try { clear(m); } 884 catch (Throwable t) { unexpected(t); } 885 } 886 887 if (supportsPut(m)) { 888 try { 889 check(m.put(3333, 77777) == null); 890 check(m.put(9134, 74982) == null); 891 check(m.get(9134) == 74982); 892 check(m.put(9134, 1382) == 74982); 893 check(m.get(9134) == 1382); 894 check(m.size() == 2); 895 checkFunctionalInvariants(m); 896 checkNPEConsistency(m); 897 } 898 catch (Throwable t) { unexpected(t); } 899 } 900 } 901 902 private static boolean supportsPut(Map<Integer,Integer> m) { 903 // We're asking for .equals(...) semantics 904 if (m instanceof IdentityHashMap) return false; 905 906 try { check(m.put(778347983,12735) == null); } 907 catch (UnsupportedOperationException t) { return false; } 908 catch (Throwable t) { unexpected(t); } 909 910 try { 911 check(m.containsKey(778347983)); 912 check(m.remove(778347983) != null); 913 } catch (Throwable t) { unexpected(t); } 914 return true; 915 } 916 917 private static boolean supportsClear(Map<?,?> m) { 918 try { m.clear(); } 919 catch (UnsupportedOperationException t) { return false; } 920 catch (Throwable t) { unexpected(t); } 921 return true; 922 } 923 924 //---------------------------------------------------------------- 925 // ConcurrentMap 926 //---------------------------------------------------------------- 927 private static void testConcurrentMap(ConcurrentMap<Integer,Integer> m) { 928 System.out.println("ConcurrentMap tests..."); 929 930 try { 931 clear(m); 932 933 check(m.putIfAbsent(18357,7346) == null); 934 check(m.containsKey(18357)); 935 check(m.putIfAbsent(18357,8263) == 7346); 936 try { m.putIfAbsent(18357,null); fail("NPE"); } 937 catch (NullPointerException t) { } 938 check(m.containsKey(18357)); 939 940 check(! m.replace(18357,8888,7777)); 941 check(m.containsKey(18357)); 942 try { m.replace(18357,null,7777); fail("NPE"); } 943 catch (NullPointerException t) { } 944 check(m.containsKey(18357)); 945 check(m.get(18357) == 7346); 946 check(m.replace(18357,7346,5555)); 947 check(m.replace(18357,5555,7346)); 948 check(m.get(18357) == 7346); 949 950 check(m.replace(92347,7834) == null); 951 try { m.replace(18357,null); fail("NPE"); } 952 catch (NullPointerException t) { } 953 check(m.replace(18357,7346) == 7346); 954 check(m.replace(18357,5555) == 7346); 955 check(m.get(18357) == 5555); 956 check(m.replace(18357,7346) == 5555); 957 check(m.get(18357) == 7346); 958 959 check(! m.remove(18357,9999)); 960 check(m.get(18357) == 7346); 961 check(m.containsKey(18357)); 962 check(! m.remove(18357,null)); // 6272521 963 check(m.get(18357) == 7346); 964 check(m.remove(18357,7346)); 965 check(m.get(18357) == null); 966 check(! m.containsKey(18357)); 967 check(m.isEmpty()); 968 969 m.putIfAbsent(1,2); 970 check(m.size() == 1); 971 check(! m.remove(1,null)); 972 check(! m.remove(1,null)); 973 check(! m.remove(1,1)); 974 check(m.remove(1,2)); 975 check(m.isEmpty()); 976 977 testEmptyMap(m); 978 } 979 catch (Throwable t) { unexpected(t); } 980 } 981 982 private static void throwsConsistently(Class<? extends Throwable> k, 983 Iterable<Fun> fs) { 984 List<Class<? extends Throwable>> threw 985 = new ArrayList<Class<? extends Throwable>>(); 986 for (Fun f : fs) 987 try { f.f(); threw.add(null); } 988 catch (Throwable t) { 989 check(k.isAssignableFrom(t.getClass())); 990 threw.add(t.getClass()); 991 } 992 if (new HashSet<Object>(threw).size() != 1) 993 fail(threw.toString()); 994 } 995 996 private static <T> void checkNPEConsistency(final Map<T,Integer> m) { 997 m.clear(); 998 final ConcurrentMap<T,Integer> cm = (m instanceof ConcurrentMap) 999 ? (ConcurrentMap<T,Integer>) m 1000 : null; 1001 List<Fun> fs = new ArrayList<Fun>(); 1002 fs.add(() -> check(! m.containsKey(null))); 1003 fs.add(() -> equal(m.remove(null), null)); 1004 fs.add(() -> equal(m.get(null), null)); 1005 if (cm != null) 1006 fs.add(() -> check(! cm.remove(null,null))); 1007 throwsConsistently(NullPointerException.class, fs); 1008 1009 fs.clear(); 1010 final Map<T,Integer> sm = singletonMap(null,1); 1011 fs.add(() -> { equal(m.put(null,1), null); m.clear();}); 1012 fs.add(() -> { m.putAll(sm); m.clear();}); 1013 if (cm != null) { 1014 fs.add(() -> check(! cm.remove(null,null))); 1015 fs.add(() -> equal(cm.putIfAbsent(null,1), 1)); 1016 fs.add(() -> equal(cm.replace(null,1), null)); 1017 fs.add(() -> equal(cm.replace(null,1, 1), 1)); 1018 } 1019 throwsConsistently(NullPointerException.class, fs); 1020 } 1021 1022 //---------------------------------------------------------------- 1023 // NavigableMap 1024 //---------------------------------------------------------------- 1025 private static void 1026 checkNavigableMapKeys(NavigableMap<Integer,Integer> m, 1027 Integer i, 1028 Integer lower, 1029 Integer floor, 1030 Integer ceiling, 1031 Integer higher) { 1032 equal(m.lowerKey(i), lower); 1033 equal(m.floorKey(i), floor); 1034 equal(m.ceilingKey(i), ceiling); 1035 equal(m.higherKey(i), higher); 1036 } 1037 1038 private static void 1039 checkNavigableSetKeys(NavigableSet<Integer> m, 1040 Integer i, 1041 Integer lower, 1042 Integer floor, 1043 Integer ceiling, 1044 Integer higher) { 1045 equal(m.lower(i), lower); 1046 equal(m.floor(i), floor); 1047 equal(m.ceiling(i), ceiling); 1048 equal(m.higher(i), higher); 1049 } 1050 1051 static final Random rnd = new Random(); 1052 static void equalNext(final Iterator<?> it, Object expected) { 1053 if (rnd.nextBoolean()) 1054 check(it.hasNext()); 1055 equal(it.next(), expected); 1056 } 1057 1058 static void equalMaps(Map m1, Map m2) { 1059 equal(m1, m2); 1060 equal(m2, m1); 1061 equal(m1.size(), m2.size()); 1062 equal(m1.isEmpty(), m2.isEmpty()); 1063 equal(m1.toString(), m2.toString()); 1064 check(Arrays.equals(m1.entrySet().toArray(), m2.entrySet().toArray())); 1065 } 1066 1067 @SuppressWarnings({"unchecked", "rawtypes"}) 1068 static void testNavigableMapRemovers(NavigableMap m) 1069 { 1070 final Map emptyMap = new HashMap(); 1071 1072 final Map singletonMap = new HashMap(); 1073 singletonMap.put(1, 2); 1074 1075 abstract class NavigableMapView { 1076 abstract NavigableMap view(NavigableMap m); 1077 } 1078 1079 NavigableMapView[] views = { 1080 new NavigableMapView() { NavigableMap view(NavigableMap m) { 1081 return m; }}, 1082 new NavigableMapView() { NavigableMap view(NavigableMap m) { 1083 return m.headMap(99, true); }}, 1084 new NavigableMapView() { NavigableMap view(NavigableMap m) { 1085 return m.tailMap(-99, false); }}, 1086 new NavigableMapView() { NavigableMap view(NavigableMap m) { 1087 return m.subMap(-99, true, 99, false); }}, 1088 }; 1089 1090 abstract class Remover { 1091 abstract void remove(NavigableMap m, Object k, Object v); 1092 } 1093 1094 Remover[] removers = { 1095 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1096 equal(m.remove(k), v); }}, 1097 1098 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1099 equal(m.descendingMap().remove(k), v); }}, 1100 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1101 equal(m.descendingMap().headMap(-86, false).remove(k), v); }}, 1102 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1103 equal(m.descendingMap().tailMap(86, true).remove(k), v); }}, 1104 1105 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1106 equal(m.headMap(86, true).remove(k), v); }}, 1107 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1108 equal(m.tailMap(-86, true).remove(k), v); }}, 1109 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1110 equal(m.subMap(-86, false, 86, true).remove(k), v); }}, 1111 1112 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1113 check(m.keySet().remove(k)); }}, 1114 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1115 check(m.navigableKeySet().remove(k)); }}, 1116 1117 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1118 check(m.navigableKeySet().headSet(86, true).remove(k)); }}, 1119 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1120 check(m.navigableKeySet().tailSet(-86, false).remove(k)); }}, 1121 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1122 check(m.navigableKeySet().subSet(-86, true, 86, false) 1123 .remove(k)); }}, 1124 1125 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1126 check(m.descendingKeySet().headSet(-86, false).remove(k)); }}, 1127 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1128 check(m.descendingKeySet().tailSet(86, true).remove(k)); }}, 1129 new Remover() { void remove(NavigableMap m, Object k, Object v) { 1130 check(m.descendingKeySet().subSet(86, true, -86, false) 1131 .remove(k)); }}, 1132 }; 1133 1134 for (NavigableMapView view : views) { 1135 for (Remover remover : removers) { 1136 try { 1137 m.clear(); 1138 equalMaps(m, emptyMap); 1139 equal(m.put(1, 2), null); 1140 equalMaps(m, singletonMap); 1141 NavigableMap v = view.view(m); 1142 remover.remove(v, 1, 2); 1143 equalMaps(m, emptyMap); 1144 } catch (Throwable t) { unexpected(t); } 1145 } 1146 } 1147 } 1148 1149 private static void testNavigableMap(NavigableMap<Integer,Integer> m) 1150 { 1151 clear(m); 1152 checkNavigableMapKeys(m, 1, null, null, null, null); 1153 1154 equal(m.put(1, 2), null); 1155 equal(m.put(3, 4), null); 1156 equal(m.put(5, 9), null); 1157 1158 equal(m.put(1, 2), 2); 1159 equal(m.put(3, 4), 4); 1160 equal(m.put(5, 6), 9); 1161 1162 checkNavigableMapKeys(m, 0, null, null, 1, 1); 1163 checkNavigableMapKeys(m, 1, null, 1, 1, 3); 1164 checkNavigableMapKeys(m, 2, 1, 1, 3, 3); 1165 checkNavigableMapKeys(m, 3, 1, 3, 3, 5); 1166 checkNavigableMapKeys(m, 5, 3, 5, 5, null); 1167 checkNavigableMapKeys(m, 6, 5, 5, null, null); 1168 1169 for (final Iterator<Integer> it : 1170 (Iterator<Integer>[]) 1171 new Iterator<?>[] { 1172 m.descendingKeySet().iterator(), 1173 m.navigableKeySet().descendingIterator()}) { 1174 equalNext(it, 5); 1175 equalNext(it, 3); 1176 equalNext(it, 1); 1177 check(! it.hasNext()); 1178 THROWS(NoSuchElementException.class, () -> it.next()); 1179 } 1180 1181 { 1182 final Iterator<Map.Entry<Integer,Integer>> it 1183 = m.descendingMap().entrySet().iterator(); 1184 check(it.hasNext()); equal(it.next().getKey(), 5); 1185 check(it.hasNext()); equal(it.next().getKey(), 3); 1186 check(it.hasNext()); equal(it.next().getKey(), 1); 1187 check(! it.hasNext()); 1188 THROWS(NoSuchElementException.class, () -> it.next()); 1189 } 1190 1191 prepMapForDescItrTests(m); 1192 checkDescItrRmFirst(m.keySet(), m.navigableKeySet().descendingIterator()); 1193 prepMapForDescItrTests(m); 1194 checkDescItrRmMid(m.keySet(), m.navigableKeySet().descendingIterator()); 1195 prepMapForDescItrTests(m); 1196 checkDescItrRmLast(m.keySet(), m.navigableKeySet().descendingIterator()); 1197 1198 prepMapForDescItrTests(m); 1199 checkDescItrRmFirst(m.keySet(), m.descendingMap().keySet().iterator()); 1200 prepMapForDescItrTests(m); 1201 checkDescItrRmMid(m.keySet(), m.descendingMap().keySet().iterator()); 1202 prepMapForDescItrTests(m); 1203 checkDescItrRmLast(m.keySet(), m.descendingMap().keySet().iterator()); 1204 1205 prepMapForDescItrTests(m); 1206 checkDescItrRmFirst(m.keySet(), m.descendingKeySet().iterator()); 1207 prepMapForDescItrTests(m); 1208 checkDescItrRmMid(m.keySet(), m.descendingKeySet().iterator()); 1209 prepMapForDescItrTests(m); 1210 checkDescItrRmLast(m.keySet(), m.descendingKeySet().iterator()); 1211 1212 prepMapForDescItrTests(m); 1213 checkDescItrRmFirst(m.values(), m.descendingMap().values().iterator()); 1214 prepMapForDescItrTests(m); 1215 checkDescItrRmMid(m.values(), m.descendingMap().values().iterator()); 1216 prepMapForDescItrTests(m); 1217 checkDescItrRmLast(m.values(), m.descendingMap().values().iterator()); 1218 1219 prepMapForDescItrTests(m); 1220 checkDescItrRmFirst((Collection)m.entrySet(), 1221 m.descendingMap().entrySet().iterator()); 1222 prepMapForDescItrTests(m); 1223 checkDescItrRmMid((Collection)m.entrySet(), 1224 m.descendingMap().entrySet().iterator()); 1225 prepMapForDescItrTests(m); 1226 checkDescItrRmLast((Collection)m.entrySet(), 1227 m.descendingMap().entrySet().iterator()); 1228 } 1229 1230 private static void testNavigableSet(NavigableSet<Integer> s) { 1231 clear(s); 1232 checkNavigableSetKeys(s, 1, null, null, null, null); 1233 1234 check(s.add(1)); 1235 check(s.add(3)); 1236 check(s.add(5)); 1237 1238 check(! s.add(1)); 1239 check(! s.add(3)); 1240 check(! s.add(5)); 1241 1242 checkNavigableSetKeys(s, 0, null, null, 1, 1); 1243 checkNavigableSetKeys(s, 1, null, 1, 1, 3); 1244 checkNavigableSetKeys(s, 2, 1, 1, 3, 3); 1245 checkNavigableSetKeys(s, 3, 1, 3, 3, 5); 1246 checkNavigableSetKeys(s, 5, 3, 5, 5, null); 1247 checkNavigableSetKeys(s, 6, 5, 5, null, null); 1248 1249 for (final Iterator<Integer> it : 1250 (Iterator<Integer>[]) 1251 new Iterator<?>[] { 1252 s.descendingIterator(), 1253 s.descendingSet().iterator()}) { 1254 equalNext(it, 5); 1255 equalNext(it, 3); 1256 equalNext(it, 1); 1257 check(! it.hasNext()); 1258 THROWS(NoSuchElementException.class, () -> it.next()); 1259 } 1260 1261 prepSetForDescItrTests(s); 1262 checkDescItrRmFirst(s, s.descendingIterator()); 1263 prepSetForDescItrTests(s); 1264 checkDescItrRmMid(s, s.descendingIterator()); 1265 prepSetForDescItrTests(s); 1266 checkDescItrRmLast(s, s.descendingIterator()); 1267 1268 prepSetForDescItrTests(s); 1269 checkDescItrRmFirst(s, s.descendingSet().iterator()); 1270 prepSetForDescItrTests(s); 1271 checkDescItrRmMid(s, s.descendingSet().iterator()); 1272 prepSetForDescItrTests(s); 1273 checkDescItrRmLast(s, s.descendingSet().iterator()); 1274 } 1275 1276 private static void prepSetForDescItrTests(Set s) { 1277 clear(s); 1278 check(s.add(1)); 1279 check(s.add(3)); 1280 check(s.add(5)); 1281 } 1282 1283 private static void prepMapForDescItrTests(Map m) { 1284 clear(m); 1285 equal(m.put(1, 2), null); 1286 equal(m.put(3, 4), null); 1287 equal(m.put(5, 9), null); 1288 } 1289 1290 //-------------------------------------------------------------------- 1291 // Check behavior of descending iterator when first element is removed 1292 //-------------------------------------------------------------------- 1293 private static <T> void checkDescItrRmFirst(Collection<T> ascColl, 1294 Iterator<T> descItr) { 1295 T[] expected = (T[]) ascColl.toArray(); 1296 int idx = expected.length -1; 1297 1298 equalNext(descItr, expected[idx--]); 1299 descItr.remove(); 1300 while(idx >= 0 && descItr.hasNext()) { 1301 equalNext(descItr, expected[idx--]); 1302 } 1303 equal(descItr.hasNext(), false); 1304 equal(idx, -1); 1305 } 1306 1307 //----------------------------------------------------------------------- 1308 // Check behavior of descending iterator when a middle element is removed 1309 //----------------------------------------------------------------------- 1310 private static <T> void checkDescItrRmMid(Collection<T> ascColl, 1311 Iterator<T> descItr) { 1312 T[] expected = (T[]) ascColl.toArray(); 1313 int idx = expected.length -1; 1314 1315 while (idx >= expected.length / 2) { 1316 equalNext(descItr, expected[idx--]); 1317 } 1318 descItr.remove(); 1319 while (idx >= 0 && descItr.hasNext()) { 1320 equalNext(descItr, expected[idx--]); 1321 } 1322 equal(descItr.hasNext(), false); 1323 equal(idx, -1); 1324 } 1325 1326 //----------------------------------------------------------------------- 1327 // Check behavior of descending iterator when the last element is removed 1328 //----------------------------------------------------------------------- 1329 private static <T> void checkDescItrRmLast(Collection<T> ascColl, 1330 Iterator<T> descItr) { 1331 T[] expected = (T[]) ascColl.toArray(); 1332 int idx = expected.length -1; 1333 1334 while (idx >= 0 && descItr.hasNext()) { 1335 equalNext(descItr, expected[idx--]); 1336 } 1337 equal(idx, -1); 1338 equal(descItr.hasNext(), false); 1339 descItr.remove(); 1340 equal(ascColl.contains(expected[0]), false); 1341 } 1342 1343 //--------------------- Infrastructure --------------------------- 1344 static volatile int passed = 0, failed = 0; 1345 static void pass() { passed++; } 1346 static void fail() { failed++; Thread.dumpStack(); } 1347 static void fail(String msg) { System.out.println(msg); fail(); } 1348 static void unexpected(Throwable t) { failed++; t.printStackTrace(); } 1349 static void check(boolean cond) { if (cond) pass(); else fail(); } 1350 static void equal(Object x, Object y) { 1351 if (x == null ? y == null : x.equals(y)) pass(); 1352 else {System.out.println(x + " not equal to " + y); fail();}} 1353 static void equal2(Object x, Object y) {equal(x, y); equal(y, x);} 1354 public static void main(String[] args) throws Throwable { 1355 try { realMain(args); } catch (Throwable t) { unexpected(t); } 1356 1357 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); 1358 if (failed > 0) throw new Exception("Some tests failed"); 1359 } 1360 interface Fun {void f() throws Throwable;} 1361 private static void THROWS(Class<? extends Throwable> k, Fun... fs) { 1362 for (Fun f : fs) 1363 try { f.f(); fail("Expected " + k.getName() + " not thrown"); } 1364 catch (Throwable t) { 1365 if (k.isAssignableFrom(t.getClass())) pass(); 1366 else unexpected(t);}} 1367 static byte[] serializedForm(Object obj) { 1368 try { 1369 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1370 new ObjectOutputStream(baos).writeObject(obj); 1371 return baos.toByteArray(); 1372 } catch (IOException e) { throw new Error(e); }} 1373 static Object readObject(byte[] bytes) 1374 throws IOException, ClassNotFoundException { 1375 InputStream is = new ByteArrayInputStream(bytes); 1376 return new ObjectInputStream(is).readObject();} 1377 @SuppressWarnings("unchecked") 1378 static <T> T serialClone(T obj) { 1379 try { return (T) readObject(serializedForm(obj)); } 1380 catch (Exception e) { throw new Error(e); }} 1381 private static class NewAbstractCollection<E> extends AbstractCollection<E> { 1382 ArrayList<E> list = new ArrayList<>(); 1383 public boolean remove(Object obj) { 1384 return list.remove(obj); 1385 } 1386 public boolean add(E e) { 1387 return list.add(e); 1388 } 1389 public Iterator<E> iterator() { 1390 return list.iterator(); 1391 } 1392 public int size() { 1393 return list.size(); 1394 } 1395 } 1396 private static class NewAbstractSet<E> extends AbstractSet<E> { 1397 HashSet<E> set = new HashSet<>(); 1398 public boolean remove(Object obj) { 1399 return set.remove(obj); 1400 } 1401 public boolean add(E e) { 1402 return set.add(e); 1403 } 1404 public Iterator<E> iterator() { 1405 return set.iterator(); 1406 } 1407 public int size() { 1408 return set.size(); 1409 } 1410 } 1411 1412 }