Path: blob/master/test/jdk/java/util/Collection/MOAT.java
41152 views
/*1* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.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 it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 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 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 6207984 6272521 6192552 6269713 6197726 6260652 5073546 413746426* 4155650 4216399 4294891 6282555 6318622 6355327 6383475 642075327* 6431845 4802633 6570566 6570575 6570631 6570924 6691185 669121528* 4802647 7123424 8024709 819312829* @summary Run many tests on many Collection and Map implementations30* @author Martin Buchholz31* @modules java.base/java.util:open32* @run main MOAT33* @key randomness34*/3536/* Mother Of All (Collection) Tests37*38* Testing of collection classes is often spotty, because many tests39* need to be performed on many implementations, but the onus on40* writing the tests falls on the engineer introducing the new41* implementation.42*43* The idea of this mega-test is that:44*45* An engineer adding a new collection implementation could simply add46* their new implementation to a list of implementations in this47* test's main method. Any general purpose Collection<Integer> or48* Map<Integer,Integer> class is appropriate.49*50* An engineer fixing a regression could add their regression test here and51* simultaneously test all other implementations.52*/5354import java.io.*;55import java.util.*;56import java.util.concurrent.*;57import static java.util.Collections.*;58import java.lang.reflect.*;59import java.util.stream.Collectors;60import java.util.stream.Stream;6162public class MOAT {63// Collections under test must not be initialized to contain this value,64// and maps under test must not contain this value as a key.65// It's used as a sentinel for absent-element testing.66static final int ABSENT_VALUE = 778347983;6768static final Integer[] integerArray;69static {70Integer[] ia = new Integer[20];71// fill with 1..20 inclusive72for (int i = 0; i < ia.length; i++) {73ia[i] = i + 1;74}75integerArray = ia;76}7778public static void realMain(String[] args) {7980testCollection(new NewAbstractCollection<Integer>());81testCollection(new NewAbstractSet<Integer>());82testCollection(new LinkedHashSet<Integer>());83testCollection(new HashSet<Integer>());84testCollection(new Vector<Integer>());85testCollection(new Vector<Integer>().subList(0,0));86testCollection(new ArrayDeque<Integer>());87testCollection(new ArrayList<Integer>());88testCollection(new ArrayList<Integer>().subList(0,0));89testCollection(new LinkedList<Integer>());90testCollection(new LinkedList<Integer>().subList(0,0));91testCollection(new TreeSet<Integer>());92testCollection(Collections.checkedList(new ArrayList<Integer>(), Integer.class));93testCollection(Collections.synchronizedList(new ArrayList<Integer>()));94testCollection(Collections.checkedSet(new HashSet<Integer>(), Integer.class));95testCollection(Collections.checkedSortedSet(new TreeSet<Integer>(), Integer.class));96testCollection(Collections.checkedNavigableSet(new TreeSet<Integer>(), Integer.class));97testCollection(Collections.synchronizedSet(new HashSet<Integer>()));98testCollection(Collections.synchronizedSortedSet(new TreeSet<Integer>()));99testCollection(Collections.synchronizedNavigableSet(new TreeSet<Integer>()));100101testCollection(new CopyOnWriteArrayList<Integer>());102testCollection(new CopyOnWriteArrayList<Integer>().subList(0,0));103testCollection(new CopyOnWriteArraySet<Integer>());104testCollection(new PriorityQueue<Integer>());105testCollection(new PriorityBlockingQueue<Integer>());106testCollection(new ArrayBlockingQueue<Integer>(20));107testCollection(new LinkedBlockingQueue<Integer>(20));108testCollection(new LinkedBlockingDeque<Integer>(20));109testCollection(new ConcurrentLinkedDeque<Integer>());110testCollection(new ConcurrentLinkedQueue<Integer>());111testCollection(new LinkedTransferQueue<Integer>());112testCollection(new ConcurrentSkipListSet<Integer>());113testCollection(Arrays.asList(new Integer(42)));114testCollection(Arrays.asList(1,2,3));115testCollection(nCopies(25,1));116testImmutableList(nCopies(25,1));117118testMap(new HashMap<Integer,Integer>());119testMap(new LinkedHashMap<Integer,Integer>());120121// TODO: Add reliable support for WeakHashMap.122// This test is subject to very rare failures because the GC123// may remove unreferenced-keys from the map at any time.124// testMap(new WeakHashMap<Integer,Integer>());125126testMap(new IdentityHashMap<Integer,Integer>());127testMap(new TreeMap<Integer,Integer>());128testMap(new Hashtable<Integer,Integer>());129testMap(new ConcurrentHashMap<Integer,Integer>(10, 0.5f));130testMap(new ConcurrentSkipListMap<Integer,Integer>());131testMap(Collections.checkedMap(new HashMap<Integer,Integer>(), Integer.class, Integer.class));132testMap(Collections.checkedSortedMap(new TreeMap<Integer,Integer>(), Integer.class, Integer.class));133testMap(Collections.checkedNavigableMap(new TreeMap<Integer,Integer>(), Integer.class, Integer.class));134testMap(Collections.synchronizedMap(new HashMap<Integer,Integer>()));135testMap(Collections.synchronizedSortedMap(new TreeMap<Integer,Integer>()));136testMap(Collections.synchronizedNavigableMap(new TreeMap<Integer,Integer>()));137138// Unmodifiable wrappers139testImmutableSet(unmodifiableSet(new HashSet<>(Arrays.asList(1,2,3))));140testImmutableList(unmodifiableList(Arrays.asList(1,2,3)));141testImmutableMap(unmodifiableMap(Collections.singletonMap(1,2)));142testCollMutatorsAlwaysThrow(unmodifiableSet(new HashSet<>(Arrays.asList(1,2,3))));143testCollMutatorsAlwaysThrow(unmodifiableSet(Collections.emptySet()));144testEmptyCollMutatorsAlwaysThrow(unmodifiableSet(Collections.emptySet()));145testListMutatorsAlwaysThrow(unmodifiableList(Arrays.asList(1,2,3)));146testListMutatorsAlwaysThrow(unmodifiableList(Collections.emptyList()));147testEmptyListMutatorsAlwaysThrow(unmodifiableList(Collections.emptyList()));148testMapMutatorsAlwaysThrow(unmodifiableMap(Collections.singletonMap(1,2)));149testMapMutatorsAlwaysThrow(unmodifiableMap(Collections.emptyMap()));150testEmptyMapMutatorsAlwaysThrow(unmodifiableMap(Collections.emptyMap()));151152// Empty collections153final List<Integer> emptyArray = Arrays.asList(new Integer[]{});154testCollection(emptyArray);155testEmptyList(emptyArray);156THROWS(IndexOutOfBoundsException.class, () -> emptyArray.set(0,1));157THROWS(UnsupportedOperationException.class, () -> emptyArray.add(0,1));158159List<Integer> noOne = nCopies(0,1);160testCollection(noOne);161testEmptyList(noOne);162testImmutableList(noOne);163164Set<Integer> emptySet = emptySet();165testCollection(emptySet);166testEmptySet(emptySet);167testEmptySet(EMPTY_SET);168testEmptySet(Collections.emptySet());169testEmptySet(Collections.emptySortedSet());170testEmptySet(Collections.emptyNavigableSet());171testImmutableSet(emptySet);172173List<Integer> emptyList = emptyList();174testCollection(emptyList);175testEmptyList(emptyList);176testEmptyList(EMPTY_LIST);177testEmptyList(Collections.emptyList());178testImmutableList(emptyList);179180Map<Integer,Integer> emptyMap = emptyMap();181testMap(emptyMap);182testEmptyMap(emptyMap);183testEmptyMap(EMPTY_MAP);184testEmptyMap(Collections.emptyMap());185testEmptyMap(Collections.emptySortedMap());186testEmptyMap(Collections.emptyNavigableMap());187testImmutableMap(emptyMap);188testImmutableMap(Collections.emptyMap());189testImmutableMap(Collections.emptySortedMap());190testImmutableMap(Collections.emptyNavigableMap());191192// Singleton collections193Set<Integer> singletonSet = singleton(1);194equal(singletonSet.size(), 1);195testCollection(singletonSet);196testImmutableSet(singletonSet);197198List<Integer> singletonList = singletonList(1);199equal(singletonList.size(), 1);200testCollection(singletonList);201testImmutableList(singletonList);202testImmutableList(singletonList.subList(0,1));203testImmutableList(singletonList.subList(0,1).subList(0,1));204testEmptyList(singletonList.subList(0,0));205testEmptyList(singletonList.subList(0,0).subList(0,0));206207Map<Integer,Integer> singletonMap = singletonMap(1,2);208equal(singletonMap.size(), 1);209testMap(singletonMap);210testImmutableMap(singletonMap);211212// Immutable List213testEmptyList(List.of());214testEmptyList(List.of().subList(0,0));215testListMutatorsAlwaysThrow(List.of());216testListMutatorsAlwaysThrow(List.<Integer>of().subList(0,0));217testEmptyListMutatorsAlwaysThrow(List.of());218testEmptyListMutatorsAlwaysThrow(List.<Integer>of().subList(0,0));219for (List<Integer> list : Arrays.asList(220List.<Integer>of(),221List.of(1),222List.of(1, 2),223List.of(1, 2, 3),224List.of(1, 2, 3, 4),225List.of(1, 2, 3, 4, 5),226List.of(1, 2, 3, 4, 5, 6),227List.of(1, 2, 3, 4, 5, 6, 7),228List.of(1, 2, 3, 4, 5, 6, 7, 8),229List.of(1, 2, 3, 4, 5, 6, 7, 8, 9),230List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),231List.of(integerArray),232Stream.<Integer>empty().toList(),233Stream.of(1).toList(),234Stream.of(1, 2).toList(),235Stream.of(1, 2, 3).toList(),236Stream.of(1, 2, 3, 4).toList(),237Stream.of((Integer)null).toList(),238Stream.of(1, null).toList(),239Stream.of(1, null, 3).toList(),240Stream.of(1, null, 3, 4).toList())) {241testCollection(list);242testImmutableList(list);243testListMutatorsAlwaysThrow(list);244if (list.size() >= 1) {245// test subLists246List<Integer> headList = list.subList(0, list.size() - 1);247List<Integer> tailList = list.subList(1, list.size());248testCollection(headList);249testCollection(tailList);250testImmutableList(headList);251testImmutableList(tailList);252testListMutatorsAlwaysThrow(headList);253testListMutatorsAlwaysThrow(tailList);254}255}256257List<Integer> listCopy = List.copyOf(Arrays.asList(1, 2, 3));258testCollection(listCopy);259testImmutableList(listCopy);260testListMutatorsAlwaysThrow(listCopy);261262List<Integer> listCollected = Stream.of(1, 2, 3).collect(Collectors.toUnmodifiableList());263equal(listCollected, List.of(1, 2, 3));264testCollection(listCollected);265testImmutableList(listCollected);266testListMutatorsAlwaysThrow(listCollected);267268// List indexOf / lastIndexOf269270// 0 element271System.out.println("testListIndexOf size 0");272testListIndexOf(-1, -1);273274System.out.println("testListIndexOf size 1");275testListIndexOf(-1, -1, 0);276testListIndexOf(0, 0, 1);277278System.out.println("testListIndexOf size 2");279testListIndexOf(-1, -1, 0, 0);280testListIndexOf(0, 0, 1, 0);281testListIndexOf(0, 1, 1, 1);282testListIndexOf(1, 1, 0, 1);283284285System.out.println("testListIndexOf size 3");286testListIndexOf(-1, -1, 0, 0, 0);287testListIndexOf(0, 0, 1, 0, 0);288testListIndexOf(0, 1, 1, 1, 0);289testListIndexOf(1, 2, 0, 1, 1);290testListIndexOf(2, 2, 0, 0, 1);291292System.out.println("testListIndexOf size N");293testListIndexOf(-1, -1, 0, 0, 0, 0, 0, 0, 0);294testListIndexOf(2, 6, 0, 0, 1, 0, 1, 0, 1);295testListIndexOf(4, 4, 0, 0, 0, 0, 1, 0, 0);296testListIndexOf(0, 6, 1, 1, 1, 1, 1, 1, 1);297testListIndexOf(0, 7, 1, 1, 1, 1, 1, 1, 1, 1);298testListIndexOf(0, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1);299testListIndexOf(0, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);300testListIndexOf(0, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);301testListIndexOf(0, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);302testListIndexOf(0, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);303testListIndexOf(12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);304testListIndexOf(-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);305306// Immutable Set307testEmptySet(Set.of());308testCollMutatorsAlwaysThrow(Set.of());309testEmptyCollMutatorsAlwaysThrow(Set.of());310for (Set<Integer> set : Arrays.asList(311Set.<Integer>of(),312Set.of(1),313Set.of(1, 2),314Set.of(1, 2, 3),315Set.of(1, 2, 3, 4),316Set.of(1, 2, 3, 4, 5),317Set.of(1, 2, 3, 4, 5, 6),318Set.of(1, 2, 3, 4, 5, 6, 7),319Set.of(1, 2, 3, 4, 5, 6, 7, 8),320Set.of(1, 2, 3, 4, 5, 6, 7, 8, 9),321Set.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),322Set.of(integerArray))) {323testCollection(set);324testImmutableSet(set);325testCollMutatorsAlwaysThrow(set);326}327328Set<Integer> setCopy = Set.copyOf(Arrays.asList(1, 2, 3));329testCollection(setCopy);330testImmutableSet(setCopy);331testCollMutatorsAlwaysThrow(setCopy);332333Set<Integer> setCollected = Stream.of(1, 1, 2, 3, 2, 3)334.collect(Collectors.toUnmodifiableSet());335equal(setCollected, Set.of(1, 2, 3));336testCollection(setCollected);337testImmutableSet(setCollected);338testCollMutatorsAlwaysThrow(setCollected);339340// Immutable Map341342@SuppressWarnings("unchecked")343Map.Entry<Integer,Integer>[] ea = (Map.Entry<Integer,Integer>[])new Map.Entry<?,?>[20];344for (int i = 0; i < ea.length; i++) {345ea[i] = Map.entry(i+1, i+101);346}347348testEmptyMap(Map.of());349testMapMutatorsAlwaysThrow(Map.of());350testEmptyMapMutatorsAlwaysThrow(Map.of());351for (Map<Integer,Integer> map : Arrays.asList(352Map.<Integer,Integer>of(),353Map.of(1, 101),354Map.of(1, 101, 2, 202),355Map.of(1, 101, 2, 202, 3, 303),356Map.of(1, 101, 2, 202, 3, 303, 4, 404),357Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505),358Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606),359Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606, 7, 707),360Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606, 7, 707, 8, 808),361Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606, 7, 707, 8, 808, 9, 909),362Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606, 7, 707, 8, 808, 9, 909, 10, 1010),363Map.ofEntries(ea))) {364testMap(map);365testImmutableMap(map);366testMapMutatorsAlwaysThrow(map);367}368369Map<Integer,Integer> mapCopy = Map.copyOf(new HashMap<>(Map.of(1, 101, 2, 202, 3, 303)));370testMap(mapCopy);371testImmutableMap(mapCopy);372testMapMutatorsAlwaysThrow(mapCopy);373374Map<Integer,Integer> mapCollected1 =375Stream.of(1, 2, 3)376.collect(Collectors.toUnmodifiableMap(i -> i, i -> 101 * i));377equal(mapCollected1, Map.of(1, 101, 2, 202, 3, 303));378testMap(mapCollected1);379testImmutableMap(mapCollected1);380testMapMutatorsAlwaysThrow(mapCollected1);381382try {383Stream.of(1, 1, 2, 3, 2, 3)384.collect(Collectors.toUnmodifiableMap(i -> i, i -> 101 * i));385fail("duplicates should have thrown an exception");386} catch (IllegalStateException ise) {387pass();388}389390Map<Integer,Integer> mapCollected2 =391Stream.of(1, 1, 2, 3, 2, 3)392.collect(Collectors.toUnmodifiableMap(i -> i, i -> 101 * i, Integer::sum));393equal(mapCollected2, Map.of(1, 202, 2, 404, 3, 606));394testMap(mapCollected2);395testImmutableMap(mapCollected2);396testMapMutatorsAlwaysThrow(mapCollected2);397}398399private static void checkContainsSelf(Collection<Integer> c) {400check(c.containsAll(c));401check(c.containsAll(Arrays.asList(c.toArray())));402check(c.containsAll(Arrays.asList(c.toArray(new Integer[0]))));403}404405private static void checkContainsEmpty(Collection<Integer> c) {406check(c.containsAll(new ArrayList<Integer>()));407}408409private static void checkUnique(Set<Integer> s) {410for (Integer i : s) {411int count = 0;412for (Integer j : s) {413if (Objects.equals(i,j))414++count;415}416check(count == 1);417}418}419420private static <T> void testEmptyCollection(Collection<T> c) {421check(c.isEmpty());422equal(c.size(), 0);423equal(c.toString(),"[]");424equal(c.toArray().length, 0);425equal(c.toArray(new Object[0]).length, 0);426equal(c.toArray(Object[]::new).length, 0);427check(c.toArray(new Object[]{42})[0] == null);428429Object[] a = new Object[1]; a[0] = Boolean.TRUE;430equal(c.toArray(a), a);431equal(a[0], null);432testEmptyIterator(c.iterator());433}434435static <T> void testEmptyIterator(final Iterator<T> it) {436if (rnd.nextBoolean())437check(! it.hasNext());438439THROWS(NoSuchElementException.class, () -> it.next());440441try { it.remove(); }442catch (IllegalStateException ignored) { pass(); }443catch (UnsupportedOperationException ignored) { pass(); }444catch (Throwable t) { unexpected(t); }445446if (rnd.nextBoolean())447check(! it.hasNext());448}449450private static void testEmptyList(List<?> c) {451testEmptyCollection(c);452equal(c.hashCode(), 1);453equal2(c, Collections.<Integer>emptyList());454}455456private static <T> void testEmptySet(Set<T> c) {457testEmptyCollection(c);458equal(c.hashCode(), 0);459equal2(c, Collections.<Integer>emptySet());460if (c instanceof NavigableSet<?>)461testEmptyIterator(((NavigableSet<T>)c).descendingIterator());462}463464private static void testImmutableCollection(final Collection<Integer> c) {465THROWS(UnsupportedOperationException.class,466() -> c.add(99),467() -> c.addAll(singleton(99)));468if (! c.isEmpty()) {469final Integer first = c.iterator().next();470THROWS(UnsupportedOperationException.class,471() -> c.clear(),472() -> c.remove(first),473() -> c.removeAll(singleton(first)),474() -> c.retainAll(emptyList()));475}476}477478private static void testImmutableSet(final Set<Integer> c) {479testImmutableCollection(c);480}481482private static void testImmutableList(final List<Integer> c) {483testList(c);484testImmutableCollection(c);485THROWS(UnsupportedOperationException.class,486() -> c.set(0,42),487() -> c.add(0,42),488() -> c.addAll(0,singleton(86)));489if (! c.isEmpty())490THROWS(UnsupportedOperationException.class,491() -> { Iterator<Integer> it = c.iterator();492it.next();493it.remove(); },494() -> { ListIterator<Integer> it = c.listIterator();495it.next();496it.remove(); });497}498499/**500* Test that calling a mutator always throws UOE, even if the mutator501* wouldn't actually do anything, given its arguments.502*503* @param c the collection instance to test504*/505private static void testCollMutatorsAlwaysThrow(Collection<Integer> c) {506THROWS(UnsupportedOperationException.class,507() -> c.addAll(Collections.emptyList()),508() -> c.remove(ABSENT_VALUE),509() -> c.removeAll(Collections.emptyList()),510() -> c.removeIf(x -> false),511() -> c.retainAll(c));512}513514/**515* Test that calling a mutator always throws UOE, even if the mutator516* wouldn't actually do anything on an empty collection.517*518* @param c the collection instance to test, must be empty519*/520private static void testEmptyCollMutatorsAlwaysThrow(Collection<Integer> c) {521if (! c.isEmpty()) {522fail("collection is not empty");523}524THROWS(UnsupportedOperationException.class,525() -> c.clear());526}527528/**529* As above, for a list.530*531* @param c the list instance to test532*/533private static void testListMutatorsAlwaysThrow(List<Integer> c) {534testCollMutatorsAlwaysThrow(c);535THROWS(UnsupportedOperationException.class,536() -> c.addAll(0, Collections.emptyList()));537}538539/**540* As above, for an empty list.541*542* @param c the list instance to test, must be empty543*/544private static void testEmptyListMutatorsAlwaysThrow(List<Integer> c) {545if (! c.isEmpty()) {546fail("list is not empty");547}548testEmptyCollMutatorsAlwaysThrow(c);549THROWS(UnsupportedOperationException.class,550() -> c.replaceAll(x -> x),551() -> c.sort(null));552}553554/**555* As above, for a map.556*557* @param m the map instance to test558*/559private static void testMapMutatorsAlwaysThrow(Map<Integer,Integer> m) {560THROWS(UnsupportedOperationException.class,561() -> m.compute(ABSENT_VALUE, (k, v) -> null),562() -> m.computeIfAbsent(ABSENT_VALUE, k -> null),563() -> m.computeIfPresent(ABSENT_VALUE, (k, v) -> null),564() -> m.merge(ABSENT_VALUE, 0, (k, v) -> null),565() -> m.putAll(Collections.emptyMap()),566() -> m.remove(ABSENT_VALUE),567() -> m.remove(ABSENT_VALUE, 0),568() -> m.replace(ABSENT_VALUE, 0),569() -> m.replace(ABSENT_VALUE, 0, 1));570}571572/**573* As above, for an empty map.574*575* @param map the map instance to test, must be empty576*/577private static void testEmptyMapMutatorsAlwaysThrow(Map<Integer,Integer> m) {578if (! m.isEmpty()) {579fail("map is not empty");580}581THROWS(UnsupportedOperationException.class,582() -> m.clear(),583() -> m.replaceAll((k, v) -> v));584}585586private static void clear(Collection<Integer> c) {587try { c.clear(); }588catch (Throwable t) { unexpected(t); }589testEmptyCollection(c);590}591592private static <K,V> void testEmptyMap(final Map<K,V> m) {593check(m.isEmpty());594equal(m.size(), 0);595equal(m.toString(),"{}");596testEmptySet(m.keySet());597testEmptySet(m.entrySet());598testEmptyCollection(m.values());599600try { check(! m.containsValue(null)); }601catch (NullPointerException ignored) { /* OK */ }602try { check(! m.containsKey(null)); }603catch (NullPointerException ignored) { /* OK */ }604check(! m.containsValue(1));605check(! m.containsKey(1));606}607608private static void testImmutableMap(final Map<Integer,Integer> m) {609THROWS(UnsupportedOperationException.class,610() -> m.put(1,1),611() -> m.putAll(singletonMap(1,1)));612if (! m.isEmpty()) {613final Integer first = m.keySet().iterator().next();614THROWS(UnsupportedOperationException.class,615() -> m.remove(first),616() -> m.clear());617final Map.Entry<Integer,Integer> me618= m.entrySet().iterator().next();619Integer key = me.getKey();620Integer val = me.getValue();621THROWS(UnsupportedOperationException.class,622() -> me.setValue(3));623equal(key, me.getKey());624equal(val, me.getValue());625}626testImmutableSet(m.keySet());627testImmutableCollection(m.values());628//testImmutableSet(m.entrySet());629}630631private static void clear(Map<?,?> m) {632try { m.clear(); }633catch (Throwable t) { unexpected(t); }634testEmptyMap(m);635}636637private static void oneElement(Collection<Integer> c) {638clear(c);639try {640check(c.add(-42));641equal(c.toString(), "[-42]");642if (c instanceof Set) check(! c.add(-42));643} catch (Throwable t) { unexpected(t); }644check(! c.isEmpty()); check(c.size() == 1);645}646647private static boolean supportsAdd(Collection<Integer> c) {648try { check(c.add(ABSENT_VALUE)); }649catch (UnsupportedOperationException t) { return false; }650catch (Throwable t) { unexpected(t); }651652try {653check(c.contains(ABSENT_VALUE));654check(c.remove(ABSENT_VALUE));655} catch (Throwable t) { unexpected(t); }656return true;657}658659private static boolean supportsRemove(Collection<Integer> c) {660try { check(! c.remove(ABSENT_VALUE)); }661catch (UnsupportedOperationException t) { return false; }662catch (Throwable t) { unexpected(t); }663return true;664}665666// 6260652: (coll) Arrays.asList(x).toArray().getClass()667// should be Object[].class668// Fixed in jdk9, but not jdk8 ...669static final boolean needToWorkAround6260652 =670Arrays.asList("").toArray().getClass() != Object[].class;671672private static void checkFunctionalInvariants(Collection<Integer> c) {673try {674checkContainsSelf(c);675checkContainsEmpty(c);676check(c.size() != 0 ^ c.isEmpty());677check(! c.contains(ABSENT_VALUE));678679{680int size = 0;681for (Integer i : c) size++;682check(c.size() == size);683}684685if (c instanceof Set) {686checkUnique((Set<Integer>)c);687}688689check(c.toArray().length == c.size());690check(c.toArray().getClass() == Object[].class691||692(needToWorkAround6260652 &&693c.getClass().getName().equals("java.util.Arrays$ArrayList")));694for (int size : new int[]{0,1,c.size(), c.size()+1}) {695Integer[] a = c.toArray(new Integer[size]);696check((size > c.size()) || a.length == c.size());697int i = 0; for (Integer j : c) check(a[i++] == j);698check((size <= c.size()) || (a[c.size()] == null));699check(a.getClass() == Integer[].class);700}701702{703Integer[] a = c.toArray(Integer[]::new);704equal(c.size(), a.length);705check(a.getClass() == Integer[].class);706check(Arrays.equals(c.toArray(new Integer[0]), a));707}708709check(c.equals(c));710if (c instanceof Serializable) {711//System.out.printf("Serializing %s%n", c.getClass().getName());712try {713Object clone = serialClone(c);714equal(c instanceof Serializable,715clone instanceof Serializable);716equal(c instanceof RandomAccess,717clone instanceof RandomAccess);718if ((c instanceof List) || (c instanceof Set))719equal(c, clone);720else721equal(new HashSet<Integer>(c),722new HashSet<Integer>(serialClone(c)));723} catch (Error xxx) {724if (! (xxx.getCause() instanceof NotSerializableException))725throw xxx;726}727}728}729catch (Throwable t) { unexpected(t); }730}731732//----------------------------------------------------------------733// If add(null) succeeds, contains(null) & remove(null) should succeed734//----------------------------------------------------------------735private static void testNullElement(Collection<Integer> c) {736737try {738check(c.add(null));739if (c.size() == 1)740equal(c.toString(), "[null]");741try {742checkFunctionalInvariants(c);743check(c.contains(null));744check(c.remove(null));745}746catch (Throwable t) { unexpected(t); }747}748catch (NullPointerException e) { /* OK */ }749catch (Throwable t) { unexpected(t); }750}751752//----------------------------------------------------------------753// If add("x") succeeds, contains("x") & remove("x") should succeed754//----------------------------------------------------------------755@SuppressWarnings("unchecked")756private static void testStringElement(Collection<Integer> c) {757Collection x = (Collection)c; // Make type-unsafe758try {759check(x.add("x"));760try {761check(x.contains("x"));762check(x.remove("x"));763} catch (Throwable t) { unexpected(t); }764}765catch (ClassCastException e) { /* OK */ }766catch (Throwable t) { unexpected(t); }767}768769private static void testConcurrentCollection(Collection<Integer> c) {770try {771c.add(1);772Iterator<Integer> it = c.iterator();773check(it.hasNext());774clear(c);775check(it.next() instanceof Integer); // No CME776check(c.isEmpty());777}778catch (Throwable t) { unexpected(t); }779}780781private static void testQueue(Queue<Integer> q) {782q.clear();783for (int i = 0; i < 5; i++) {784testQueueAddRemove(q, null);785testQueueAddRemove(q, 537);786q.add(i);787}788equal(q.size(), 5);789checkFunctionalInvariants(q);790q.poll();791equal(q.size(), 4);792checkFunctionalInvariants(q);793if ((q instanceof LinkedBlockingQueue) ||794(q instanceof LinkedBlockingDeque) ||795(q instanceof ConcurrentLinkedDeque) ||796(q instanceof ConcurrentLinkedQueue)) {797testQueueIteratorRemove(q);798}799}800801private static void testQueueAddRemove(final Queue<Integer> q,802final Integer e) {803final List<Integer> originalContents = new ArrayList<>(q);804final boolean isEmpty = q.isEmpty();805final boolean isList = (q instanceof List);806final List asList = isList ? (List) q : null;807check(!q.contains(e));808try {809q.add(e);810} catch (NullPointerException npe) {811check(e == null);812return; // Null elements not supported813}814check(q.contains(e));815check(q.remove(e));816check(!q.contains(e));817equal(new ArrayList<Integer>(q), originalContents);818819if (q instanceof Deque<?>) {820final Deque<Integer> deq = (Deque<Integer>) q;821final List<Integer> singleton = Collections.singletonList(e);822823// insert, query, remove element at head824if (isEmpty) {825THROWS(NoSuchElementException.class,826() -> deq.getFirst(),827() -> deq.element(),828() -> deq.iterator().next());829check(deq.peekFirst() == null);830check(deq.peek() == null);831} else {832check(deq.getFirst() != e);833check(deq.element() != e);834check(deq.iterator().next() != e);835check(deq.peekFirst() != e);836check(deq.peek() != e);837}838check(!deq.contains(e));839check(!deq.removeFirstOccurrence(e));840check(!deq.removeLastOccurrence(e));841if (isList) {842check(asList.indexOf(e) == -1);843check(asList.lastIndexOf(e) == -1);844}845switch (rnd.nextInt(isList ? 4 : 3)) {846case 0: deq.addFirst(e); break;847case 1: check(deq.offerFirst(e)); break;848case 2: deq.push(e); break;849case 3: asList.add(0, e); break;850default: throw new AssertionError();851}852check(deq.peekFirst() == e);853check(deq.getFirst() == e);854check(deq.element() == e);855check(deq.peek() == e);856check(deq.iterator().next() == e);857check(deq.contains(e));858if (isList) {859check(asList.get(0) == e);860check(asList.indexOf(e) == 0);861check(asList.lastIndexOf(e) == 0);862check(asList.subList(0, 1).equals(singleton));863}864switch (rnd.nextInt(isList ? 11 : 9)) {865case 0: check(deq.pollFirst() == e); break;866case 1: check(deq.removeFirst() == e); break;867case 2: check(deq.remove() == e); break;868case 3: check(deq.pop() == e); break;869case 4: check(deq.removeFirstOccurrence(e)); break;870case 5: check(deq.removeLastOccurrence(e)); break;871case 6: check(deq.remove(e)); break;872case 7: check(deq.removeAll(singleton)); break;873case 8: Iterator it = deq.iterator(); it.next(); it.remove(); break;874case 9: asList.remove(0); break;875case 10: asList.subList(0, 1).clear(); break;876default: throw new AssertionError();877}878if (isEmpty) {879THROWS(NoSuchElementException.class,880() -> deq.getFirst(),881() -> deq.element(),882() -> deq.iterator().next());883check(deq.peekFirst() == null);884check(deq.peek() == null);885} else {886check(deq.getFirst() != e);887check(deq.element() != e);888check(deq.iterator().next() != e);889check(deq.peekFirst() != e);890check(deq.peek() != e);891}892check(!deq.contains(e));893check(!deq.removeFirstOccurrence(e));894check(!deq.removeLastOccurrence(e));895if (isList) {896check(isEmpty || asList.get(0) != e);897check(asList.indexOf(e) == -1);898check(asList.lastIndexOf(e) == -1);899}900equal(new ArrayList<Integer>(deq), originalContents);901902// insert, query, remove element at tail903if (isEmpty) {904check(deq.peekLast() == null);905THROWS(NoSuchElementException.class, () -> deq.getLast());906} else {907check(deq.peekLast() != e);908check(deq.getLast() != e);909}910switch (rnd.nextInt(isList ? 6 : 4)) {911case 0: deq.addLast(e); break;912case 1: check(deq.offerLast(e)); break;913case 2: check(deq.add(e)); break;914case 3: deq.addAll(singleton); break;915case 4: asList.addAll(deq.size(), singleton); break;916case 5: asList.add(deq.size(), e); break;917default: throw new AssertionError();918}919check(deq.peekLast() == e);920check(deq.getLast() == e);921check(deq.contains(e));922if (isList) {923ListIterator it = asList.listIterator(asList.size());924check(it.previous() == e);925check(asList.get(asList.size() - 1) == e);926check(asList.indexOf(e) == asList.size() - 1);927check(asList.lastIndexOf(e) == asList.size() - 1);928int size = asList.size();929check(asList.subList(size - 1, size).equals(singleton));930}931switch (rnd.nextInt(isList ? 8 : 6)) {932case 0: check(deq.pollLast() == e); break;933case 1: check(deq.removeLast() == e); break;934case 2: check(deq.removeFirstOccurrence(e)); break;935case 3: check(deq.removeLastOccurrence(e)); break;936case 4: check(deq.remove(e)); break;937case 5: check(deq.removeAll(singleton)); break;938case 6: asList.remove(asList.size() - 1); break;939case 7:940ListIterator it = asList.listIterator(asList.size());941it.previous();942it.remove();943break;944default: throw new AssertionError();945}946if (isEmpty) {947check(deq.peekLast() == null);948THROWS(NoSuchElementException.class, () -> deq.getLast());949} else {950check(deq.peekLast() != e);951check(deq.getLast() != e);952}953check(!deq.contains(e));954equal(new ArrayList<Integer>(deq), originalContents);955956// Test operations on empty deque957switch (rnd.nextInt(isList ? 4 : 2)) {958case 0: deq.clear(); break;959case 1:960Iterator it = deq.iterator();961while (it.hasNext()) {962it.next();963it.remove();964}965break;966case 2: asList.subList(0, asList.size()).clear(); break;967case 3:968ListIterator lit = asList.listIterator(asList.size());969while (lit.hasPrevious()) {970lit.previous();971lit.remove();972}973break;974default: throw new AssertionError();975}976testEmptyCollection(deq);977check(!deq.iterator().hasNext());978if (isList) {979check(!asList.listIterator().hasPrevious());980THROWS(NoSuchElementException.class,981() -> asList.listIterator().previous());982}983THROWS(NoSuchElementException.class,984() -> deq.iterator().next(),985() -> deq.element(),986() -> deq.getFirst(),987() -> deq.getLast(),988() -> deq.pop(),989() -> deq.remove(),990() -> deq.removeFirst(),991() -> deq.removeLast());992993check(deq.poll() == null);994check(deq.pollFirst() == null);995check(deq.pollLast() == null);996check(deq.peek() == null);997check(deq.peekFirst() == null);998check(deq.peekLast() == null);999check(!deq.removeFirstOccurrence(e));1000check(!deq.removeLastOccurrence(e));10011002check(deq.addAll(originalContents) == !isEmpty);1003equal(new ArrayList<Integer>(deq), originalContents);1004check(!deq.addAll(Collections.<Integer>emptyList()));1005equal(new ArrayList<Integer>(deq), originalContents);1006}1007}10081009private static void testQueueIteratorRemove(Queue<Integer> q) {1010System.err.printf("testQueueIteratorRemove %s%n",1011q.getClass().getSimpleName());1012q.clear();1013for (int i = 0; i < 5; i++)1014q.add(i);1015Iterator<Integer> it = q.iterator();1016check(it.hasNext());1017for (int i = 3; i >= 0; i--)1018q.remove(i);1019equal(it.next(), 0);1020equal(it.next(), 4);10211022q.clear();1023for (int i = 0; i < 5; i++)1024q.add(i);1025it = q.iterator();1026equal(it.next(), 0);1027check(it.hasNext());1028for (int i = 1; i < 4; i++)1029q.remove(i);1030equal(it.next(), 1);1031equal(it.next(), 4);1032}10331034// for any array of integer values, check that the result of lastIndexOf(1)1035// and indexOf(1) match assumptions for all types of List<Integer> we can1036// construct1037private static void testListIndexOf(final int index,1038final int lastIndex,1039final Integer ... values) {1040if (values.length == 0) {1041checkListIndexOf(emptyList(), index, lastIndex);1042} else if (values.length == 1) {1043checkListIndexOf(singletonList(values[0]), index, lastIndex);1044checkListIndexOf(nCopies(25, values[0]), index, lastIndex == 0 ? 24 : -1);1045}1046List<Integer> l = List.of(values);1047checkListIndexOf(l, index, lastIndex);1048checkListIndexOf(Arrays.asList(values), index, lastIndex);1049checkListIndexOf(new ArrayList(l), index, lastIndex);1050checkListIndexOf(new LinkedList(l), index, lastIndex);1051checkListIndexOf(new Vector(l), index, lastIndex);1052checkListIndexOf(new CopyOnWriteArrayList(l), index, lastIndex);1053}10541055private static void checkListIndexOf(final List<Integer> list,1056final int index,1057final int lastIndex) {1058String msg = list.getClass().toString();1059equal(list.indexOf(1), index, msg);1060equal(list.lastIndexOf(1), lastIndex, msg);1061equal(list.subList(0, list.size()).indexOf(1), index, msg);1062equal(list.subList(0, list.size()).lastIndexOf(1), lastIndex, msg);1063}10641065private static void testList(final List<Integer> l) {1066//----------------------------------------------------------------1067// 4802633: (coll) AbstractList.addAll(-1,emptyCollection)1068// doesn't throw IndexOutOfBoundsException1069//----------------------------------------------------------------1070try {1071l.addAll(-1, Collections.<Integer>emptyList());1072fail("Expected IndexOutOfBoundsException not thrown");1073}1074catch (UnsupportedOperationException ignored) {/* OK */}1075catch (IndexOutOfBoundsException ignored) {/* OK */}1076catch (Throwable t) { unexpected(t); }10771078// equal(l instanceof Serializable,1079// l.subList(0,0) instanceof Serializable);1080if (l.subList(0,0) instanceof Serializable)1081check(l instanceof Serializable);10821083equal(l instanceof RandomAccess,1084l.subList(0,0) instanceof RandomAccess);10851086l.iterator();1087l.listIterator();1088l.listIterator(0);1089l.listIterator(l.size());1090THROWS(IndexOutOfBoundsException.class,1091() -> l.listIterator(-1),1092() -> l.listIterator(l.size() + 1));10931094if (l instanceof AbstractList) {1095try {1096int size = l.size();1097AbstractList<Integer> abList = (AbstractList<Integer>) l;1098Method m = AbstractList.class.getDeclaredMethod("removeRange", new Class[] { int.class, int.class });1099m.setAccessible(true);1100m.invoke(abList, new Object[] { 0, 0 });1101m.invoke(abList, new Object[] { size, size });1102equal(size, l.size());1103}1104catch (UnsupportedOperationException ignored) {/* OK */}1105catch (Throwable t) { unexpected(t); }1106}11071108int hashCode = 1;1109for (Integer i : l)1110hashCode = 31 * hashCode + (i == null ? 0 : i.hashCode());1111check(l.hashCode() == hashCode);11121113var t = new ArrayList<>(l);1114check(t.equals(l));1115check(l.equals(t));1116}11171118private static void testCollection(Collection<Integer> c) {1119try { testCollection1(c); }1120catch (Throwable t) { unexpected(t); }1121}11221123private static void testCollection1(Collection<Integer> c) {11241125System.out.println("\n==> " + c.getClass().getName());11261127checkFunctionalInvariants(c);11281129if (! supportsAdd(c)) return;1130//System.out.println("add() supported");11311132if (c instanceof NavigableSet) {1133System.out.println("NavigableSet tests...");11341135NavigableSet<Integer> ns = (NavigableSet<Integer>)c;1136testNavigableSet(ns);1137testNavigableSet(ns.headSet(6, false));1138testNavigableSet(ns.headSet(5, true));1139testNavigableSet(ns.tailSet(0, false));1140testNavigableSet(ns.tailSet(1, true));1141testNavigableSet(ns.subSet(0, false, 5, true));1142testNavigableSet(ns.subSet(1, true, 6, false));1143}11441145if (c instanceof Queue)1146testQueue((Queue<Integer>)c);11471148if (c instanceof List)1149testList((List<Integer>)c);11501151if (c instanceof Set) {1152int hashCode = 0;1153for (Integer i : c)1154hashCode = hashCode + (i == null ? 0 : i.hashCode());1155check(c.hashCode() == hashCode);1156}11571158check(supportsRemove(c));11591160try {1161oneElement(c);1162checkFunctionalInvariants(c);1163}1164catch (Throwable t) { unexpected(t); }11651166clear(c); testNullElement(c);1167oneElement(c); testNullElement(c);11681169clear(c); testStringElement(c);1170oneElement(c); testStringElement(c);11711172if (c.getClass().getName().matches(".*concurrent.*"))1173testConcurrentCollection(c);11741175//----------------------------------------------------------------1176// The "all" operations should throw NPE when passed null1177//----------------------------------------------------------------1178{1179clear(c);1180try {1181c.removeAll(null);1182fail("Expected NullPointerException");1183}1184catch (NullPointerException e) { pass(); }1185catch (Throwable t) { unexpected(t); }11861187oneElement(c);1188try {1189c.removeAll(null);1190fail("Expected NullPointerException");1191}1192catch (NullPointerException e) { pass(); }1193catch (Throwable t) { unexpected(t); }11941195clear(c);1196try {1197c.retainAll(null);1198fail("Expected NullPointerException");1199}1200catch (NullPointerException e) { pass(); }1201catch (Throwable t) { unexpected(t); }12021203oneElement(c);1204try {1205c.retainAll(null);1206fail("Expected NullPointerException");1207}1208catch (NullPointerException e) { pass(); }1209catch (Throwable t) { unexpected(t); }12101211oneElement(c);1212try {1213c.addAll(null);1214fail("Expected NullPointerException");1215}1216catch (NullPointerException e) { pass(); }1217catch (Throwable t) { unexpected(t); }12181219oneElement(c);1220try {1221c.containsAll(null);1222fail("Expected NullPointerException");1223}1224catch (NullPointerException e) { pass(); }1225catch (Throwable t) { unexpected(t); }1226}1227}12281229//----------------------------------------------------------------1230// Map1231//----------------------------------------------------------------1232private static void checkFunctionalInvariants(Map<Integer,Integer> m) {1233check(m.keySet().size() == m.entrySet().size());1234check(m.keySet().size() == m.size());1235checkFunctionalInvariants(m.keySet());1236checkFunctionalInvariants(m.values());1237check(m.size() != 0 ^ m.isEmpty());1238check(! m.containsKey(ABSENT_VALUE));12391240if (m instanceof Serializable) {1241//System.out.printf("Serializing %s%n", m.getClass().getName());1242try {1243Object clone = serialClone(m);1244equal(m instanceof Serializable,1245clone instanceof Serializable);1246equal(m, clone);1247} catch (Error xxx) {1248if (! (xxx.getCause() instanceof NotSerializableException))1249throw xxx;1250}1251}1252}12531254private static void testMap(Map<Integer,Integer> m) {1255System.out.println("\n==> " + m.getClass().getName());12561257int hashCode = 0;1258for (var e : m.entrySet()) {1259int entryHash = (e.getKey() == null ? 0 : e.getKey().hashCode()) ^1260(e.getValue() == null ? 0 : e.getValue().hashCode());1261check(e.hashCode() == entryHash);1262hashCode += entryHash;1263}1264check(m.hashCode() == hashCode);12651266if (m instanceof ConcurrentMap)1267testConcurrentMap((ConcurrentMap<Integer,Integer>) m);12681269if (m instanceof NavigableMap) {1270System.out.println("NavigableMap tests...");12711272NavigableMap<Integer,Integer> nm =1273(NavigableMap<Integer,Integer>) m;1274testNavigableMapRemovers(nm);1275testNavigableMap(nm);1276testNavigableMap(nm.headMap(6, false));1277testNavigableMap(nm.headMap(5, true));1278testNavigableMap(nm.tailMap(0, false));1279testNavigableMap(nm.tailMap(1, true));1280testNavigableMap(nm.subMap(1, true, 6, false));1281testNavigableMap(nm.subMap(0, false, 5, true));1282}12831284checkFunctionalInvariants(m);12851286if (supportsClear(m)) {1287try { clear(m); }1288catch (Throwable t) { unexpected(t); }1289}12901291if (supportsPut(m)) {1292try {1293check(m.put(3333, 77777) == null);1294check(m.put(9134, 74982) == null);1295check(m.get(9134) == 74982);1296check(m.put(9134, 1382) == 74982);1297check(m.get(9134) == 1382);1298check(m.size() == 2);1299checkFunctionalInvariants(m);1300checkNPEConsistency(m);1301}1302catch (Throwable t) { unexpected(t); }1303}1304}13051306private static boolean supportsPut(Map<Integer,Integer> m) {1307// We're asking for .equals(...) semantics1308if (m instanceof IdentityHashMap) return false;13091310try { check(m.put(ABSENT_VALUE,12735) == null); }1311catch (UnsupportedOperationException t) { return false; }1312catch (Throwable t) { unexpected(t); }13131314try {1315check(m.containsKey(ABSENT_VALUE));1316check(m.remove(ABSENT_VALUE) != null);1317} catch (Throwable t) { unexpected(t); }1318return true;1319}13201321private static boolean supportsClear(Map<?,?> m) {1322try { m.clear(); }1323catch (UnsupportedOperationException t) { return false; }1324catch (Throwable t) { unexpected(t); }1325return true;1326}13271328//----------------------------------------------------------------1329// ConcurrentMap1330//----------------------------------------------------------------1331private static void testConcurrentMap(ConcurrentMap<Integer,Integer> m) {1332System.out.println("ConcurrentMap tests...");13331334try {1335clear(m);13361337check(m.putIfAbsent(18357,7346) == null);1338check(m.containsKey(18357));1339check(m.putIfAbsent(18357,8263) == 7346);1340try { m.putIfAbsent(18357,null); fail("NPE"); }1341catch (NullPointerException t) { }1342check(m.containsKey(18357));13431344check(! m.replace(18357,8888,7777));1345check(m.containsKey(18357));1346try { m.replace(18357,null,7777); fail("NPE"); }1347catch (NullPointerException t) { }1348check(m.containsKey(18357));1349check(m.get(18357) == 7346);1350check(m.replace(18357,7346,5555));1351check(m.replace(18357,5555,7346));1352check(m.get(18357) == 7346);13531354check(m.replace(92347,7834) == null);1355try { m.replace(18357,null); fail("NPE"); }1356catch (NullPointerException t) { }1357check(m.replace(18357,7346) == 7346);1358check(m.replace(18357,5555) == 7346);1359check(m.get(18357) == 5555);1360check(m.replace(18357,7346) == 5555);1361check(m.get(18357) == 7346);13621363check(! m.remove(18357,9999));1364check(m.get(18357) == 7346);1365check(m.containsKey(18357));1366check(! m.remove(18357,null)); // 62725211367check(m.get(18357) == 7346);1368check(m.remove(18357,7346));1369check(m.get(18357) == null);1370check(! m.containsKey(18357));1371check(m.isEmpty());13721373m.putIfAbsent(1,2);1374check(m.size() == 1);1375check(! m.remove(1,null));1376check(! m.remove(1,null));1377check(! m.remove(1,1));1378check(m.remove(1,2));1379check(m.isEmpty());13801381testEmptyMap(m);1382}1383catch (Throwable t) { unexpected(t); }1384}13851386private static void throwsConsistently(Class<? extends Throwable> k,1387Iterable<Fun> fs) {1388List<Class<? extends Throwable>> threw = new ArrayList<>();1389for (Fun f : fs)1390try { f.f(); threw.add(null); }1391catch (Throwable t) {1392check(k.isAssignableFrom(t.getClass()));1393threw.add(t.getClass());1394}1395if (new HashSet<Object>(threw).size() != 1)1396fail(threw.toString());1397}13981399private static <T> void checkNPEConsistency(final Map<T,Integer> m) {1400m.clear();1401final ConcurrentMap<T,Integer> cm = (m instanceof ConcurrentMap)1402? (ConcurrentMap<T,Integer>) m1403: null;1404List<Fun> fs = new ArrayList<>();1405fs.add(() -> check(! m.containsKey(null)));1406fs.add(() -> equal(m.remove(null), null));1407fs.add(() -> equal(m.get(null), null));1408if (cm != null)1409fs.add(() -> check(! cm.remove(null,null)));1410throwsConsistently(NullPointerException.class, fs);14111412fs.clear();1413final Map<T,Integer> sm = singletonMap(null,1);1414fs.add(() -> { equal(m.put(null,1), null); m.clear();});1415fs.add(() -> { m.putAll(sm); m.clear();});1416if (cm != null) {1417fs.add(() -> check(! cm.remove(null,null)));1418fs.add(() -> equal(cm.putIfAbsent(null,1), 1));1419fs.add(() -> equal(cm.replace(null,1), null));1420fs.add(() -> equal(cm.replace(null,1, 1), 1));1421}1422throwsConsistently(NullPointerException.class, fs);1423}14241425//----------------------------------------------------------------1426// NavigableMap1427//----------------------------------------------------------------1428private static void1429checkNavigableMapKeys(NavigableMap<Integer,Integer> m,1430Integer i,1431Integer lower,1432Integer floor,1433Integer ceiling,1434Integer higher) {1435equal(m.lowerKey(i), lower);1436equal(m.floorKey(i), floor);1437equal(m.ceilingKey(i), ceiling);1438equal(m.higherKey(i), higher);1439}14401441private static void1442checkNavigableSetKeys(NavigableSet<Integer> m,1443Integer i,1444Integer lower,1445Integer floor,1446Integer ceiling,1447Integer higher) {1448equal(m.lower(i), lower);1449equal(m.floor(i), floor);1450equal(m.ceiling(i), ceiling);1451equal(m.higher(i), higher);1452}14531454static final Random rnd = new Random();1455static void equalNext(final Iterator<?> it, Object expected) {1456if (rnd.nextBoolean())1457check(it.hasNext());1458equal(it.next(), expected);1459}14601461static void equalMaps(Map m1, Map m2) {1462equal(m1, m2);1463equal(m2, m1);1464equal(m1.size(), m2.size());1465equal(m1.isEmpty(), m2.isEmpty());1466equal(m1.toString(), m2.toString());1467check(Arrays.equals(m1.entrySet().toArray(), m2.entrySet().toArray()));1468}14691470@SuppressWarnings({"unchecked", "rawtypes"})1471static void testNavigableMapRemovers(NavigableMap m)1472{1473final Map emptyMap = new HashMap();14741475final Map singletonMap = new HashMap();1476singletonMap.put(1, 2);14771478abstract class NavigableMapView {1479abstract NavigableMap view(NavigableMap m);1480}14811482NavigableMapView[] views = {1483new NavigableMapView() { NavigableMap view(NavigableMap m) {1484return m; }},1485new NavigableMapView() { NavigableMap view(NavigableMap m) {1486return m.headMap(99, true); }},1487new NavigableMapView() { NavigableMap view(NavigableMap m) {1488return m.tailMap(-99, false); }},1489new NavigableMapView() { NavigableMap view(NavigableMap m) {1490return m.subMap(-99, true, 99, false); }},1491};14921493abstract class Remover {1494abstract void remove(NavigableMap m, Object k, Object v);1495}14961497Remover[] removers = {1498new Remover() { void remove(NavigableMap m, Object k, Object v) {1499equal(m.remove(k), v); }},15001501new Remover() { void remove(NavigableMap m, Object k, Object v) {1502equal(m.descendingMap().remove(k), v); }},1503new Remover() { void remove(NavigableMap m, Object k, Object v) {1504equal(m.descendingMap().headMap(-86, false).remove(k), v); }},1505new Remover() { void remove(NavigableMap m, Object k, Object v) {1506equal(m.descendingMap().tailMap(86, true).remove(k), v); }},15071508new Remover() { void remove(NavigableMap m, Object k, Object v) {1509equal(m.headMap(86, true).remove(k), v); }},1510new Remover() { void remove(NavigableMap m, Object k, Object v) {1511equal(m.tailMap(-86, true).remove(k), v); }},1512new Remover() { void remove(NavigableMap m, Object k, Object v) {1513equal(m.subMap(-86, false, 86, true).remove(k), v); }},15141515new Remover() { void remove(NavigableMap m, Object k, Object v) {1516check(m.keySet().remove(k)); }},1517new Remover() { void remove(NavigableMap m, Object k, Object v) {1518check(m.navigableKeySet().remove(k)); }},15191520new Remover() { void remove(NavigableMap m, Object k, Object v) {1521check(m.navigableKeySet().headSet(86, true).remove(k)); }},1522new Remover() { void remove(NavigableMap m, Object k, Object v) {1523check(m.navigableKeySet().tailSet(-86, false).remove(k)); }},1524new Remover() { void remove(NavigableMap m, Object k, Object v) {1525check(m.navigableKeySet().subSet(-86, true, 86, false)1526.remove(k)); }},15271528new Remover() { void remove(NavigableMap m, Object k, Object v) {1529check(m.descendingKeySet().headSet(-86, false).remove(k)); }},1530new Remover() { void remove(NavigableMap m, Object k, Object v) {1531check(m.descendingKeySet().tailSet(86, true).remove(k)); }},1532new Remover() { void remove(NavigableMap m, Object k, Object v) {1533check(m.descendingKeySet().subSet(86, true, -86, false)1534.remove(k)); }},1535};15361537for (NavigableMapView view : views) {1538for (Remover remover : removers) {1539try {1540m.clear();1541equalMaps(m, emptyMap);1542equal(m.put(1, 2), null);1543equalMaps(m, singletonMap);1544NavigableMap v = view.view(m);1545remover.remove(v, 1, 2);1546equalMaps(m, emptyMap);1547} catch (Throwable t) { unexpected(t); }1548}1549}1550}15511552private static void testNavigableMap(NavigableMap<Integer,Integer> m)1553{1554clear(m);1555checkNavigableMapKeys(m, 1, null, null, null, null);15561557equal(m.put(1, 2), null);1558equal(m.put(3, 4), null);1559equal(m.put(5, 9), null);15601561equal(m.put(1, 2), 2);1562equal(m.put(3, 4), 4);1563equal(m.put(5, 6), 9);15641565checkNavigableMapKeys(m, 0, null, null, 1, 1);1566checkNavigableMapKeys(m, 1, null, 1, 1, 3);1567checkNavigableMapKeys(m, 2, 1, 1, 3, 3);1568checkNavigableMapKeys(m, 3, 1, 3, 3, 5);1569checkNavigableMapKeys(m, 5, 3, 5, 5, null);1570checkNavigableMapKeys(m, 6, 5, 5, null, null);15711572for (final Iterator<Integer> it :1573(Iterator<Integer>[])1574new Iterator<?>[] {1575m.descendingKeySet().iterator(),1576m.navigableKeySet().descendingIterator()}) {1577equalNext(it, 5);1578equalNext(it, 3);1579equalNext(it, 1);1580check(! it.hasNext());1581THROWS(NoSuchElementException.class, () -> it.next());1582}15831584{1585final Iterator<Map.Entry<Integer,Integer>> it1586= m.descendingMap().entrySet().iterator();1587check(it.hasNext()); equal(it.next().getKey(), 5);1588check(it.hasNext()); equal(it.next().getKey(), 3);1589check(it.hasNext()); equal(it.next().getKey(), 1);1590check(! it.hasNext());1591THROWS(NoSuchElementException.class, () -> it.next());1592}15931594prepMapForDescItrTests(m);1595checkDescItrRmFirst(m.keySet(), m.navigableKeySet().descendingIterator());1596prepMapForDescItrTests(m);1597checkDescItrRmMid(m.keySet(), m.navigableKeySet().descendingIterator());1598prepMapForDescItrTests(m);1599checkDescItrRmLast(m.keySet(), m.navigableKeySet().descendingIterator());16001601prepMapForDescItrTests(m);1602checkDescItrRmFirst(m.keySet(), m.descendingMap().keySet().iterator());1603prepMapForDescItrTests(m);1604checkDescItrRmMid(m.keySet(), m.descendingMap().keySet().iterator());1605prepMapForDescItrTests(m);1606checkDescItrRmLast(m.keySet(), m.descendingMap().keySet().iterator());16071608prepMapForDescItrTests(m);1609checkDescItrRmFirst(m.keySet(), m.descendingKeySet().iterator());1610prepMapForDescItrTests(m);1611checkDescItrRmMid(m.keySet(), m.descendingKeySet().iterator());1612prepMapForDescItrTests(m);1613checkDescItrRmLast(m.keySet(), m.descendingKeySet().iterator());16141615prepMapForDescItrTests(m);1616checkDescItrRmFirst(m.values(), m.descendingMap().values().iterator());1617prepMapForDescItrTests(m);1618checkDescItrRmMid(m.values(), m.descendingMap().values().iterator());1619prepMapForDescItrTests(m);1620checkDescItrRmLast(m.values(), m.descendingMap().values().iterator());16211622prepMapForDescItrTests(m);1623checkDescItrRmFirst((Collection)m.entrySet(),1624m.descendingMap().entrySet().iterator());1625prepMapForDescItrTests(m);1626checkDescItrRmMid((Collection)m.entrySet(),1627m.descendingMap().entrySet().iterator());1628prepMapForDescItrTests(m);1629checkDescItrRmLast((Collection)m.entrySet(),1630m.descendingMap().entrySet().iterator());1631}16321633private static void testNavigableSet(NavigableSet<Integer> s) {1634clear(s);1635checkNavigableSetKeys(s, 1, null, null, null, null);16361637check(s.add(1));1638check(s.add(3));1639check(s.add(5));16401641check(! s.add(1));1642check(! s.add(3));1643check(! s.add(5));16441645checkNavigableSetKeys(s, 0, null, null, 1, 1);1646checkNavigableSetKeys(s, 1, null, 1, 1, 3);1647checkNavigableSetKeys(s, 2, 1, 1, 3, 3);1648checkNavigableSetKeys(s, 3, 1, 3, 3, 5);1649checkNavigableSetKeys(s, 5, 3, 5, 5, null);1650checkNavigableSetKeys(s, 6, 5, 5, null, null);16511652for (final Iterator<Integer> it :1653(Iterator<Integer>[])1654new Iterator<?>[] {1655s.descendingIterator(),1656s.descendingSet().iterator()}) {1657equalNext(it, 5);1658equalNext(it, 3);1659equalNext(it, 1);1660check(! it.hasNext());1661THROWS(NoSuchElementException.class, () -> it.next());1662}16631664prepSetForDescItrTests(s);1665checkDescItrRmFirst(s, s.descendingIterator());1666prepSetForDescItrTests(s);1667checkDescItrRmMid(s, s.descendingIterator());1668prepSetForDescItrTests(s);1669checkDescItrRmLast(s, s.descendingIterator());16701671prepSetForDescItrTests(s);1672checkDescItrRmFirst(s, s.descendingSet().iterator());1673prepSetForDescItrTests(s);1674checkDescItrRmMid(s, s.descendingSet().iterator());1675prepSetForDescItrTests(s);1676checkDescItrRmLast(s, s.descendingSet().iterator());1677}16781679private static void prepSetForDescItrTests(Set s) {1680clear(s);1681check(s.add(1));1682check(s.add(3));1683check(s.add(5));1684}16851686private static void prepMapForDescItrTests(Map m) {1687clear(m);1688equal(m.put(1, 2), null);1689equal(m.put(3, 4), null);1690equal(m.put(5, 9), null);1691}16921693//--------------------------------------------------------------------1694// Check behavior of descending iterator when first element is removed1695//--------------------------------------------------------------------1696private static <T> void checkDescItrRmFirst(Collection<T> ascColl,1697Iterator<T> descItr) {1698T[] expected = (T[]) ascColl.toArray();1699int idx = expected.length -1;17001701equalNext(descItr, expected[idx--]);1702descItr.remove();1703while (idx >= 0 && descItr.hasNext()) {1704equalNext(descItr, expected[idx--]);1705}1706equal(descItr.hasNext(), false);1707equal(idx, -1);1708}17091710//-----------------------------------------------------------------------1711// Check behavior of descending iterator when a middle element is removed1712//-----------------------------------------------------------------------1713private static <T> void checkDescItrRmMid(Collection<T> ascColl,1714Iterator<T> descItr) {1715T[] expected = (T[]) ascColl.toArray();1716int idx = expected.length -1;17171718while (idx >= expected.length / 2) {1719equalNext(descItr, expected[idx--]);1720}1721descItr.remove();1722while (idx >= 0 && descItr.hasNext()) {1723equalNext(descItr, expected[idx--]);1724}1725equal(descItr.hasNext(), false);1726equal(idx, -1);1727}17281729//-----------------------------------------------------------------------1730// Check behavior of descending iterator when the last element is removed1731//-----------------------------------------------------------------------1732private static <T> void checkDescItrRmLast(Collection<T> ascColl,1733Iterator<T> descItr) {1734T[] expected = (T[]) ascColl.toArray();1735int idx = expected.length -1;17361737while (idx >= 0 && descItr.hasNext()) {1738equalNext(descItr, expected[idx--]);1739}1740equal(idx, -1);1741equal(descItr.hasNext(), false);1742descItr.remove();1743equal(ascColl.contains(expected[0]), false);1744}17451746//--------------------- Infrastructure ---------------------------1747static volatile int passed = 0, failed = 0;1748static void pass() { passed++; }1749static void fail() { failed++; Thread.dumpStack(); }1750static void fail(String msg) { System.out.println(msg); fail(); }1751static void unexpected(Throwable t) { failed++; t.printStackTrace(); }1752static void check(boolean cond) { if (cond) pass(); else fail(); }1753static void equal(Object x, Object y) {1754if (x == null ? y == null : x.equals(y)) pass();1755else {System.out.println(x + " not equal to " + y); fail();}}1756static void equal(Object x, Object y, String msg) {1757if (x == null ? y == null : x.equals(y)) pass();1758else {System.out.println(x + " not equal to " + y + " : " + msg); fail();}}1759static void equal2(Object x, Object y) {equal(x, y); equal(y, x);}1760public static void main(String[] args) throws Throwable {1761try { realMain(args); } catch (Throwable t) { unexpected(t); }17621763System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);1764if (failed > 0) throw new Exception("Some tests failed");1765}1766interface Fun {void f() throws Throwable;}1767private static void THROWS(Class<? extends Throwable> k, Fun... fs) {1768for (Fun f : fs)1769try { f.f(); fail("Expected " + k.getName() + " not thrown"); }1770catch (Throwable t) {1771if (k.isAssignableFrom(t.getClass())) pass();1772else unexpected(t);}}1773static byte[] serializedForm(Object obj) {1774try {1775ByteArrayOutputStream baos = new ByteArrayOutputStream();1776new ObjectOutputStream(baos).writeObject(obj);1777return baos.toByteArray();1778} catch (IOException e) { throw new Error(e); }}1779static Object readObject(byte[] bytes)1780throws IOException, ClassNotFoundException {1781InputStream is = new ByteArrayInputStream(bytes);1782return new ObjectInputStream(is).readObject();}1783@SuppressWarnings("unchecked")1784static <T> T serialClone(T obj) {1785try { return (T) readObject(serializedForm(obj)); }1786catch (Exception e) { throw new Error(e); }}1787private static class NewAbstractCollection<E> extends AbstractCollection<E> {1788ArrayList<E> list = new ArrayList<>();1789public boolean remove(Object obj) {1790return list.remove(obj);1791}1792public boolean add(E e) {1793return list.add(e);1794}1795public Iterator<E> iterator() {1796return list.iterator();1797}1798public int size() {1799return list.size();1800}1801}1802private static class NewAbstractSet<E> extends AbstractSet<E> {1803HashSet<E> set = new HashSet<>();1804public boolean remove(Object obj) {1805return set.remove(obj);1806}1807public boolean add(E e) {1808return set.add(e);1809}1810public Iterator<E> iterator() {1811return set.iterator();1812}1813public int size() {1814return set.size();1815}1816}18171818}181918201821