test/java/util/Map/Defaults.java

Print this page
rev 6845 : 8004518: Add in-place operations to Map
8010122: Add atomic operations to Map
Reviewed-by: darcy, briangoetz, mduigou
Contributed-by: Doug Lea <dl at cs.oswego.edu>, Henry Jen <henry.jen@oracle.com>, Akhil Arora <akhil.arora@oracle.com>, Peter Levart <peter.levart@gmail.com>


   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 8008785
  27  * @summary Ensure toArray() implementations return correct results.
  28  * @author Mike Duigou

  29  */
  30 import java.util.*;












  31 import java.util.concurrent.ConcurrentHashMap;
  32 import java.util.concurrent.ConcurrentSkipListMap;

  33 
  34 public class ToArray {















































































































































































































  35 










































































































  36     /**
  37      * Number of elements per map.
  38      */
  39     private static final int TEST_SIZE = 5000;
  40 
  41     private static void realMain(String[] args) throws Throwable {
  42         Map<Integer, Long>[] maps = (Map<Integer, Long>[]) new Map[]{
  43                     new HashMap<>(),
  44                     new Hashtable<>(),
  45                     new IdentityHashMap<>(),
  46                     new LinkedHashMap<>(),
  47                     new TreeMap<>(),
  48                     new WeakHashMap<>(),
  49                     new ConcurrentHashMap<>(),
  50                     new ConcurrentSkipListMap<>()
  51                 };
  52 
  53         // for each map type.
  54         for (Map<Integer, Long> map : maps) {
  55              try {
  56                 testMap(map);
  57              } catch(Exception all) {
  58                 unexpected("Failed for " + map.getClass().getName(), all);
  59              }
  60         }
  61     }
  62 
  63     private static final Integer[] KEYS = new Integer[TEST_SIZE];
  64 
  65     private static final Long[] VALUES = new Long[TEST_SIZE];
  66 
  67     static {

  68         for (int each = 0; each < TEST_SIZE; each++) {
  69             KEYS[each]   = Integer.valueOf(each);
  70             VALUES[each] = Long.valueOf(each + TEST_SIZE);
  71         }
  72     }


  73 




  74 
  75     private static void testMap(Map<Integer, Long> map) {
  76         System.out.println("Testing " + map.getClass());
  77         System.out.flush();
  78 
  79         // Fill the map
  80         for (int each = 0; each < TEST_SIZE; each++) {
  81             map.put(KEYS[each], VALUES[each]);
  82         }
  83 
  84         // check the keys
  85         Object[] keys = map.keySet().toArray();
  86         Arrays.sort(keys);

  87 
  88         for(int each = 0; each < TEST_SIZE; each++) {
  89             check( "unexpected key", keys[each] == KEYS[each]);

  90         }
  91 
  92         // check the values
  93         Object[] values = map.values().toArray();
  94         Arrays.sort(values);
  95 
  96         for(int each = 0; each < TEST_SIZE; each++) {
  97             check( "unexpected value", values[each] == VALUES[each]);



  98         }
  99 
 100         // check the entries
 101         Map.Entry<Integer,Long>[] entries = map.entrySet().toArray(new Map.Entry[TEST_SIZE]);
 102         Arrays.sort( entries,new Comparator<Map.Entry<Integer,Long>>() {
 103                 public int compare(Map.Entry<Integer,Long> o1, Map.Entry<Integer,Long> o2) {
 104                         return o1.getKey().compareTo(o2.getKey());
 105                 }});
 106 
 107         for(int each = 0; each < TEST_SIZE; each++) {
 108             check( "unexpected entry", entries[each].getKey() == KEYS[each] && entries[each].getValue() == VALUES[each]);
 109         }

 110     }
 111 
 112     //--------------------- Infrastructure ---------------------------
 113     static volatile int passed = 0, failed = 0;
 114 
 115     static void pass() {
 116         passed++;
 117     }


 118 
 119     static void fail() {
 120         failed++;
 121         (new Error("Failure")).printStackTrace(System.err);
 122     }
 123 
 124     static void fail(String msg) {
 125         failed++;
 126         (new Error("Failure: " + msg)).printStackTrace(System.err);
 127     }
 128 
 129     static void abort() {
 130         fail();
 131         System.exit(1);


 132     }
 133 
 134     static void abort(String msg) {
 135         fail(msg);
 136         System.exit(1);





 137     }
 138 
 139     static void unexpected(String msg, Throwable t) {
 140         System.err.println("Unexpected: " + msg);
 141         unexpected(t);







 142     }
 143 
 144     static void unexpected(Throwable t) {
 145         failed++;
 146         t.printStackTrace(System.err);

 147     }
 148 
 149     static void check(boolean cond) {
 150         if (cond) {
 151             pass();



 152         } else {
 153             fail();
 154         }
 155     }
 156 
 157     static void check(String desc, boolean cond) {
 158         if (cond) {
 159             pass();
 160         } else {
 161             fail(desc);
 162         }
 163     }
 164 
 165     static void equal(Object x, Object y) {
 166         if (Objects.equals(x, y)) {
 167             pass();
 168         } else {
 169             fail(x + " not equal to " + y);
 170         }



 171     }
 172 
 173     public static void main(String[] args) throws Throwable {
 174         Thread.currentThread().setName(ToArray.class.getName());
 175 //        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
 176         try {
 177             realMain(args);
 178         } catch (Throwable t) {
 179             unexpected(t);







 180         }
 181 
 182         System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
 183         if (failed > 0) {
 184             throw new Error("Some tests failed");
 185         }



 186     }
 187 }


   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 8010122 8004518
  27  * @summary Test Map default methods
  28  * @author Mike Duigou
  29  * @run testng Defaults
  30  */
  31 import java.util.ArrayList;
  32 import java.util.Arrays;
  33 import java.util.Collection;
  34 import java.util.Collections;
  35 import java.util.EnumMap;
  36 import java.util.HashMap;
  37 import java.util.Hashtable;
  38 import java.util.IdentityHashMap;
  39 import java.util.Iterator;
  40 import java.util.LinkedHashMap;
  41 import java.util.Map;
  42 import java.util.TreeMap;
  43 import java.util.WeakHashMap;
  44 import java.util.concurrent.ConcurrentHashMap;
  45 import java.util.concurrent.ConcurrentSkipListMap;
  46 import java.util.function.Supplier;
  47 
  48 import org.testng.annotations.Test;
  49 import org.testng.annotations.DataProvider;
  50 import static org.testng.Assert.fail;
  51 import static org.testng.Assert.assertEquals;
  52 import static org.testng.Assert.assertTrue;
  53 import static org.testng.Assert.assertFalse;
  54 import static org.testng.Assert.assertNull;
  55 import static org.testng.Assert.assertSame;
  56 
  57 public class Defaults {
  58 
  59     @Test(dataProvider = "Nulls Map<IntegerEnum,String>")
  60     public void testGetOrDefaultNulls(String description, Map<IntegerEnum, String> map) {
  61         assertTrue(map.containsKey(null), "null key absent");
  62         assertNull(map.get(null), "value not null");
  63         assertSame(map.get(null), map.getOrDefault(null, EXTRA_VALUE), "values should match");
  64     }
  65 
  66     @Test(dataProvider = "Map<IntegerEnum,String>")
  67     public void testGetOrDefault(String description, Map<IntegerEnum, String> map) {
  68         assertTrue(map.containsKey(KEYS[1]), "expected key missing");
  69         assertSame(map.get(KEYS[1]), map.getOrDefault(KEYS[1], EXTRA_VALUE), "values should match");
  70         assertFalse(map.containsKey(EXTRA_KEY), "expected absent key");
  71         assertSame(map.getOrDefault(EXTRA_KEY, EXTRA_VALUE), EXTRA_VALUE, "value not returned as default");
  72         assertNull(map.getOrDefault(EXTRA_KEY, null), "null not returned as default");
  73     }
  74 
  75     @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
  76     public void testPutIfAbsentNulls(String description, Map<IntegerEnum, String> map) {
  77         assertTrue(map.containsKey(null), "null key absent");
  78         assertNull(map.get(null), "value not null");
  79         assertNull(map.putIfAbsent(null, EXTRA_VALUE), "previous not null");
  80         assertTrue(map.containsKey(null), "null key absent");
  81         assertSame(map.get(null), EXTRA_VALUE, "unexpected value");
  82         assertSame(map.putIfAbsent(null, null), EXTRA_VALUE, "previous not expected value");
  83         assertTrue(map.containsKey(null), "null key absent");
  84         assertSame(map.get(null), EXTRA_VALUE, "unexpected value");
  85         assertSame(map.remove(null), EXTRA_VALUE, "removed unexpected value");
  86 
  87         assertFalse(map.containsKey(null), description + ": key present after remove");
  88         assertNull(map.putIfAbsent(null, null), "previous not null");
  89         assertTrue(map.containsKey(null), "null key absent");
  90         assertNull(map.get(null), "value not null");
  91         assertNull(map.putIfAbsent(null, EXTRA_VALUE), "previous not null");
  92         assertSame(map.get(null), EXTRA_VALUE, "value not expected");
  93     }
  94 
  95     @Test(dataProvider = "R/W Map<IntegerEnum,String>")
  96     public void testPutIfAbsent(String description, Map<IntegerEnum, String> map) {
  97         assertTrue(map.containsKey(KEYS[1]));
  98         Object expected = map.get(KEYS[1]);
  99         assertTrue(null == expected || expected == VALUES[1]);
 100         assertSame(map.putIfAbsent(KEYS[1], EXTRA_VALUE), expected);
 101         assertSame(map.get(KEYS[1]), expected);
 102 
 103         assertFalse(map.containsKey(EXTRA_KEY));
 104         assertSame(map.putIfAbsent(EXTRA_KEY, EXTRA_VALUE), null);
 105         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 106     }
 107 
 108     @Test(dataProvider = "Nulls Map<IntegerEnum,String>")
 109     public void testForEach(String description, Map<IntegerEnum, String> map) {
 110         IntegerEnum[] EACH_KEY = new IntegerEnum[map.size()];
 111 
 112         map.forEach((k, v) -> {
 113             int idx = (null == k) ? 0 : k.ordinal(); // substitute for index.
 114             assertNull(EACH_KEY[idx]);
 115             EACH_KEY[idx] = (idx == 0) ? KEYS[0] : k; // substitute for comparison.
 116             assertSame(v, map.get(k));
 117         });
 118 
 119         assertEquals(KEYS, EACH_KEY);
 120     }
 121 
 122     @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
 123     public static void testRemoveNulls(String description, Map<IntegerEnum, String> map) {
 124         assertTrue(map.containsKey(null), "null key absent");
 125         assertNull(map.get(null), "value not null");
 126         assertFalse(map.remove(null, EXTRA_VALUE), description);
 127         assertTrue(map.containsKey(null));
 128         assertNull(map.get(null));
 129         assertTrue(map.remove(null, null));
 130         assertFalse(map.containsKey(null));
 131         assertNull(map.get(null));
 132         assertFalse(map.remove(null, null));
 133     }
 134 
 135     @Test(dataProvider = "R/W Map<IntegerEnum,String>")
 136     public static void testRemove(String description, Map<IntegerEnum, String> map) {
 137         assertTrue(map.containsKey(KEYS[1]));
 138         Object expected = map.get(KEYS[1]);
 139         assertTrue(null == expected || expected == VALUES[1]);
 140         assertFalse(map.remove(KEYS[1], EXTRA_VALUE), description);
 141         assertSame(map.get(KEYS[1]), expected);
 142         assertTrue(map.remove(KEYS[1], expected));
 143         assertNull(map.get(KEYS[1]));
 144         assertFalse(map.remove(KEYS[1], expected));
 145 
 146         assertFalse(map.containsKey(EXTRA_KEY));
 147         assertFalse(map.remove(EXTRA_KEY, EXTRA_VALUE));
 148     }
 149 
 150     @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
 151     public void testReplaceKVNulls(String description, Map<IntegerEnum, String> map) {
 152         assertTrue(map.containsKey(null), "null key absent");
 153         assertNull(map.get(null), "value not null");
 154         assertSame(map.replace(null, EXTRA_VALUE), null);
 155         assertSame(map.get(null), EXTRA_VALUE);
 156     }
 157 
 158     @Test(dataProvider = "R/W Map<IntegerEnum,String>")
 159     public void testReplaceKV(String description, Map<IntegerEnum, String> map) {
 160         assertTrue(map.containsKey(KEYS[1]));
 161         Object expected = map.get(KEYS[1]);
 162         assertTrue(null == expected || expected == VALUES[1]);
 163         assertSame(map.replace(KEYS[1], EXTRA_VALUE), expected);
 164         assertSame(map.get(KEYS[1]), EXTRA_VALUE);
 165 
 166         assertFalse(map.containsKey(EXTRA_KEY));
 167         assertNull(map.replace(EXTRA_KEY, EXTRA_VALUE));
 168         assertFalse(map.containsKey(EXTRA_KEY));
 169         assertNull(map.get(EXTRA_KEY));
 170         assertNull(map.put(EXTRA_KEY, EXTRA_VALUE));
 171         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 172         assertSame(map.replace(EXTRA_KEY, (String)expected), EXTRA_VALUE);
 173         assertSame(map.get(EXTRA_KEY), expected);
 174     }
 175 
 176     @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
 177     public void testReplaceKVVNulls(String description, Map<IntegerEnum, String> map) {
 178         assertTrue(map.containsKey(null), "null key absent");
 179         assertNull(map.get(null), "value not null");
 180         assertFalse(map.replace(null, EXTRA_VALUE, EXTRA_VALUE));
 181         assertNull(map.get(null));
 182         assertTrue(map.replace(null, null, EXTRA_VALUE));
 183         assertSame(map.get(null), EXTRA_VALUE);
 184         assertTrue(map.replace(null, EXTRA_VALUE, EXTRA_VALUE));
 185         assertSame(map.get(null), EXTRA_VALUE);
 186     }
 187 
 188     @Test(dataProvider = "R/W Map<IntegerEnum,String>")
 189     public void testReplaceKVV(String description, Map<IntegerEnum, String> map) {
 190         assertTrue(map.containsKey(KEYS[1]));
 191         Object expected = map.get(KEYS[1]);
 192         assertTrue(null == expected || expected == VALUES[1]);
 193         assertFalse(map.replace(KEYS[1], EXTRA_VALUE, EXTRA_VALUE));
 194         assertSame(map.get(KEYS[1]), expected);
 195         assertTrue(map.replace(KEYS[1], (String)expected, EXTRA_VALUE));
 196         assertSame(map.get(KEYS[1]), EXTRA_VALUE);
 197         assertTrue(map.replace(KEYS[1], EXTRA_VALUE, EXTRA_VALUE));
 198         assertSame(map.get(KEYS[1]), EXTRA_VALUE);
 199 
 200         assertFalse(map.containsKey(EXTRA_KEY));
 201         assertFalse(map.replace(EXTRA_KEY, EXTRA_VALUE, EXTRA_VALUE));
 202         assertFalse(map.containsKey(EXTRA_KEY));
 203         assertNull(map.get(EXTRA_KEY));
 204         assertNull(map.put(EXTRA_KEY, EXTRA_VALUE));
 205         assertTrue(map.containsKey(EXTRA_KEY));
 206         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 207         assertTrue(map.replace(EXTRA_KEY, EXTRA_VALUE, EXTRA_VALUE));
 208         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 209     }
 210 
 211     @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
 212     public void testComputeIfAbsentNulls(String description, Map<IntegerEnum, String> map) {
 213         assertTrue(map.containsKey(null), "null key absent");
 214         assertNull(map.get(null), "value not null");
 215         assertSame(map.computeIfAbsent(null, (k) -> EXTRA_VALUE), EXTRA_VALUE, description);
 216         assertSame(map.get(null), EXTRA_VALUE, description);
 217     }
 218 
 219     @Test(dataProvider = "R/W Map<IntegerEnum,String>")
 220     public void testComputeIfAbsent(String description, Map<IntegerEnum, String> map) {
 221         assertTrue(map.containsKey(KEYS[1]));
 222         Object expected = map.get(KEYS[1]);
 223         assertTrue(null == expected || expected == VALUES[1], description + String.valueOf(expected));
 224         expected = (null == expected) ? EXTRA_VALUE : expected;
 225         assertSame(map.computeIfAbsent(KEYS[1], (k) -> EXTRA_VALUE), expected, description);
 226         assertSame(map.get(KEYS[1]), expected, description);
 227 
 228         assertFalse(map.containsKey(EXTRA_KEY));
 229         assertSame(map.computeIfAbsent(EXTRA_KEY, (k) -> EXTRA_VALUE), EXTRA_VALUE);
 230         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 231     }
 232 
 233     @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
 234     public void testComputeIfPresentNulls(String description, Map<IntegerEnum, String> map) {
 235         assertTrue(map.containsKey(null));
 236         assertNull(map.get(null));
 237         assertSame(map.computeIfPresent(null, (k, v) -> {
 238             fail();
 239             return EXTRA_VALUE;
 240         }), null, description);
 241         assertTrue(map.containsKey(null));
 242         assertSame(map.get(null), null, description);
 243     }
 244 
 245     @Test(dataProvider = "R/W Map<IntegerEnum,String>")
 246     public void testComputeIfPresent(String description, Map<IntegerEnum, String> map) {
 247         assertTrue(map.containsKey(KEYS[1]));
 248         Object value = map.get(KEYS[1]);
 249         assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
 250         Object expected = (null == value) ? null : EXTRA_VALUE;
 251         assertSame(map.computeIfPresent(KEYS[1], (k, v) -> {
 252             assertSame(v, value);
 253             return EXTRA_VALUE;
 254         }), expected, description);
 255         assertSame(map.get(KEYS[1]), expected, description);
 256 
 257         assertFalse(map.containsKey(EXTRA_KEY));
 258         assertSame(map.computeIfPresent(EXTRA_KEY, (k, v) -> {
 259             fail();
 260             return EXTRA_VALUE;
 261         }), null);
 262         assertFalse(map.containsKey(EXTRA_KEY));
 263         assertSame(map.get(EXTRA_KEY), null);
 264     }
 265 
 266     @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
 267     public void testComputeNulls(String description, Map<IntegerEnum, String> map) {
 268         assertTrue(map.containsKey(null), "null key absent");
 269         assertNull(map.get(null), "value not null");
 270         assertSame(map.compute(null, (k, v) -> {
 271             assertSame(k, null);
 272             assertNull(v);
 273             return EXTRA_VALUE;
 274         }), EXTRA_VALUE, description);
 275         assertTrue(map.containsKey(null));
 276         assertSame(map.get(null), EXTRA_VALUE, description);
 277     }
 278 
 279     @Test(dataProvider = "R/W Map<IntegerEnum,String>")
 280     public void testCompute(String description, Map<IntegerEnum, String> map) {
 281         assertTrue(map.containsKey(KEYS[1]));
 282         Object value = map.get(KEYS[1]);
 283         assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
 284         assertSame(map.compute(KEYS[1], (k, v) -> {
 285             assertSame(k, KEYS[1]);
 286             assertSame(v, value);
 287             return EXTRA_VALUE;
 288         }), EXTRA_VALUE, description);
 289         assertSame(map.get(KEYS[1]), EXTRA_VALUE, description);
 290         assertNull(map.compute(KEYS[1], (k, v) -> {
 291             assertSame(v, EXTRA_VALUE);
 292             return null;
 293         }), description);
 294         assertFalse(map.containsKey(KEYS[1]));
 295 
 296         assertFalse(map.containsKey(EXTRA_KEY));
 297         assertSame(map.compute(EXTRA_KEY, (k, v) -> {
 298             assertNull(v);
 299             return EXTRA_VALUE;
 300         }), EXTRA_VALUE);
 301         assertTrue(map.containsKey(EXTRA_KEY));
 302         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 303     }
 304 
 305 
 306     @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
 307     public void testMergeNulls(String description, Map<IntegerEnum, String> map) {
 308         assertTrue(map.containsKey(null), "null key absent");
 309         assertNull(map.get(null), "value not null");
 310         assertSame(map.merge(null, EXTRA_VALUE, (v, vv) -> {
 311             assertNull(v);
 312             assertSame(vv, EXTRA_VALUE);
 313             return vv;
 314         }), EXTRA_VALUE, description);
 315         assertTrue(map.containsKey(null));
 316         assertSame(map.get(null), EXTRA_VALUE, description);
 317     }
 318 
 319     @Test(dataProvider = "R/W Map<IntegerEnum,String>")
 320     public void testMerge(String description, Map<IntegerEnum, String> map) {
 321         assertTrue(map.containsKey(KEYS[1]));
 322         Object value = map.get(KEYS[1]);
 323         assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
 324         assertSame(map.merge(KEYS[1], EXTRA_VALUE, (v, vv) -> {
 325             assertSame(v, value);
 326             assertSame(vv, EXTRA_VALUE);
 327             return vv;
 328         }), EXTRA_VALUE, description);
 329         assertSame(map.get(KEYS[1]), EXTRA_VALUE, description);
 330         assertNull(map.merge(KEYS[1], EXTRA_VALUE, (v, vv) -> {
 331             assertSame(v, EXTRA_VALUE);
 332             assertSame(vv, EXTRA_VALUE);
 333             return null;
 334         }), description);
 335         assertFalse(map.containsKey(KEYS[1]));
 336 
 337         assertFalse(map.containsKey(EXTRA_KEY));
 338         assertSame(map.merge(EXTRA_KEY, EXTRA_VALUE, (v, vv) -> {
 339             assertNull(v);
 340             assertSame(vv, EXTRA_VALUE);
 341             return EXTRA_VALUE;
 342         }), EXTRA_VALUE);
 343         assertTrue(map.containsKey(EXTRA_KEY));
 344         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 345     }
 346 
 347     enum IntegerEnum {
 348 
 349         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9,
 350         e10, e11, e12, e13, e14, e15, e16, e17, e18, e19,
 351         e20, e21, e22, e23, e24, e25, e26, e27, e28, e29,
 352         e30, e31, e32, e33, e34, e35, e36, e37, e38, e39,
 353         e40, e41, e42, e43, e44, e45, e46, e47, e48, e49,
 354         e50, e51, e52, e53, e54, e55, e56, e57, e58, e59,
 355         e60, e61, e62, e63, e64, e65, e66, e67, e68, e69,
 356         e70, e71, e72, e73, e74, e75, e76, e77, e78, e79,
 357         e80, e81, e82, e83, e84, e85, e86, e87, e88, e89,
 358         e90, e91, e92, e93, e94, e95, e96, e97, e98, e99,
 359         EXTRA_KEY;
 360         public static final int SIZE = values().length;
 361     };
 362     private static final int TEST_SIZE = IntegerEnum.SIZE - 1;
 363     /**
 364      * Realized keys ensure that there is always a hard ref to all test objects.
 365      */
 366     private static final IntegerEnum[] KEYS = new IntegerEnum[TEST_SIZE];
 367     /**
 368      * Realized values ensure that there is always a hard ref to all test
 369      * objects.
 370      */
 371     private static final String[] VALUES = new String[TEST_SIZE];





















 372 
 373     static {
 374         IntegerEnum[] keys = IntegerEnum.values();
 375         for (int each = 0; each < TEST_SIZE; each++) {
 376             KEYS[each] = keys[each];
 377             VALUES[each] = String.valueOf(each);
 378         }
 379     }
 380     private static final IntegerEnum EXTRA_KEY = IntegerEnum.EXTRA_KEY;
 381     private static final String EXTRA_VALUE = String.valueOf(TEST_SIZE);
 382 
 383     @DataProvider(name = "Map<IntegerEnum,String>", parallel = true)
 384     public static Iterator<Object[]> allNullsMapProvider() {
 385         return makeAllMaps().iterator();
 386     }
 387 
 388     @DataProvider(name = "Nulls Map<IntegerEnum,String>", parallel = true)
 389     public static Iterator<Object[]> allMapProvider() {
 390         return makeRWMaps(true).iterator();




 391     }
 392 
 393     @DataProvider(name = "R/W Map<IntegerEnum,String>", parallel = true)
 394     public static Iterator<Object[]> rwMapProvider() {
 395         return makeRWMapsNoNulls().iterator();
 396     }
 397 
 398     @DataProvider(name = "R/W Nulls Map<IntegerEnum,String>", parallel = true)
 399     public static Iterator<Object[]> rwNullsMapProvider() {
 400         return makeRWMaps(true).iterator();
 401     }
 402 
 403     private static Collection<Object[]> makeAllMapsNoNulls() {
 404         Collection<Object[]> all = new ArrayList<>();

 405 
 406         all.addAll(makeRWMaps(false));
 407         all.addAll(makeRWNoNullsMaps());
 408         all.addAll(makeROMaps(false));
 409 
 410         return all;
 411     }
 412 
 413     private static Collection<Object[]> makeRWMapsNoNulls() {
 414         Collection<Object[]> all = new ArrayList<>();




 415 
 416         all.addAll(makeRWMaps(false));
 417         all.addAll(makeRWNoNullsMaps());
 418 
 419         return all;
 420     }
 421 
 422     private static Collection<Object[]> makeAllMaps() {
 423         Collection<Object[]> all = new ArrayList<>();
 424 
 425         all.addAll(makeROMaps(false));
 426         all.addAll(makeRWMaps(false));
 427         all.addAll(makeRWNoNullsMaps());
 428         all.addAll(makeRWMaps(true));
 429         all.addAll(makeROMaps(true));
 430 
 431         return all;


 432     }
 433 
 434     private static Collection<Object[]> makeAllRWMaps() {
 435         Collection<Object[]> all = new ArrayList<>();


 436 
 437         all.addAll(makeRWMaps(false));
 438         all.addAll(makeRWNoNullsMaps());
 439         all.addAll(makeRWMaps(true));
 440 
 441         return all;
 442     }
 443 
 444     private static Collection<Object[]> makeRWMaps(boolean nulls) {
 445         return Arrays.asList(
 446             new Object[]{"HashMap", makeMap(HashMap::new, nulls)},
 447             new Object[]{"IdentityHashMap", makeMap(IdentityHashMap::new, nulls)},
 448             new Object[]{"LinkedHashMap", makeMap(LinkedHashMap::new, nulls)},
 449             new Object[]{"WeakHashMap", makeMap(WeakHashMap::new, nulls)},
 450             new Object[]{"Collections.checkedMap(HashMap)", Collections.checkedMap(makeMap(HashMap::new, nulls), IntegerEnum.class, String.class)},
 451             new Object[]{"Collections.synchronizedMap(HashMap)", Collections.synchronizedMap(makeMap(HashMap::new, nulls))});
 452     }
 453 
 454     private static Collection<Object[]> makeRWNoNullsMaps() {
 455         return Arrays.asList(
 456             // null hostile
 457             new Object[]{"EnumMap", makeMap(() -> new EnumMap(IntegerEnum.class), false)},
 458             new Object[]{"Hashtable", makeMap(Hashtable::new, false)},
 459             new Object[]{"TreeMap", makeMap(TreeMap::new, false)},
 460             new Object[]{"ConcurrentHashMap", makeMap(ConcurrentHashMap::new, false)},
 461             new Object[]{"ConcurrentSkipListMap", makeMap(ConcurrentSkipListMap::new, false)},
 462             new Object[]{"Collections.checkedMap(ConcurrentHashMap)", Collections.checkedMap(makeMap(ConcurrentHashMap::new, false), IntegerEnum.class, String.class)},
 463             new Object[]{"Collections.synchronizedMap(EnumMap)", Collections.synchronizedMap(makeMap(() -> new EnumMap(IntegerEnum.class), false))});
 464     }
 465 
 466     private static Collection<Object[]> makeROMaps(boolean nulls) {
 467         return Arrays.asList(new Object[][]{
 468             new Object[]{"Collections.unmodifiableMap(HashMap)", Collections.unmodifiableMap(makeMap(HashMap::new, nulls))}
 469         });
 470     }
 471 
 472     private static Map<IntegerEnum, String> makeMap(Supplier<Map<IntegerEnum, String>> supplier, boolean nulls) {
 473         Map<IntegerEnum, String> result = supplier.get();
 474 
 475         for (int each = 0; each < TEST_SIZE; each++) {
 476             if (nulls) {
 477                 result.put((each == 0) ? null : KEYS[each], null);
 478             } else {
 479                 result.put(KEYS[each], VALUES[each]);
 480             }
 481         }
 482 
 483         return result;





 484     }
 485 
 486     public interface Thrower<T extends Throwable> {
 487 
 488         public void run() throws T;


 489     }
 490 
 491     public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable) {
 492         assertThrows(thrower, throwable, null);
 493     }
 494 
 495     public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable, String message) {
 496         Throwable result;

 497         try {
 498             thrower.run();
 499             result = null;
 500         } catch (Throwable caught) {
 501             result = caught;
 502         }
 503 
 504         assertInstance(result, throwable,
 505             (null != message)
 506             ? message
 507             : "Failed to throw " + throwable.getCanonicalName());
 508     }
 509 
 510     public static <T> void assertInstance(T actual, Class<? extends T> expected) {
 511         assertInstance(expected.isInstance(actual), null);

 512     }
 513 
 514     public static <T> void assertInstance(T actual, Class<? extends T> expected, String message) {
 515         assertTrue(expected.isInstance(actual), message);
 516     }
 517 }