1 /* 2 * Copyright (c) 2013, 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 8010122 8004518 27 * @summary Test Map default methods 28 * @author Mike Duigou 29 * @run testng Defaults 30 */ 31 import java.util.AbstractMap; 32 import java.util.AbstractSet; 33 import java.util.ArrayList; 34 import java.util.Arrays; 35 import java.util.Collection; 36 import java.util.Collections; 37 import java.util.EnumMap; 38 import java.util.HashMap; 39 import java.util.Hashtable; 40 import java.util.IdentityHashMap; 41 import java.util.Iterator; 42 import java.util.LinkedHashMap; 43 import java.util.Map; 44 import java.util.TreeMap; 45 import java.util.Set; 46 import java.util.WeakHashMap; 47 import java.util.concurrent.ConcurrentMap; 48 import java.util.concurrent.ConcurrentHashMap; 49 import java.util.concurrent.ConcurrentSkipListMap; 50 import java.util.function.Supplier; 51 52 import org.testng.annotations.Test; 53 import org.testng.annotations.DataProvider; 54 import static org.testng.Assert.fail; 55 import static org.testng.Assert.assertEquals; 56 import static org.testng.Assert.assertTrue; 57 import static org.testng.Assert.assertFalse; 58 import static org.testng.Assert.assertNull; 59 import static org.testng.Assert.assertSame; 60 61 public class Defaults { 62 63 @Test(dataProvider = "Nulls Map<IntegerEnum,String>") 64 public void testGetOrDefaultNulls(String description, Map<IntegerEnum, String> map) { 65 assertTrue(map.containsKey(null), "null key absent"); 66 assertNull(map.get(null), "value not null"); 67 assertSame(map.get(null), map.getOrDefault(null, EXTRA_VALUE), "values should match"); 68 } 69 70 @Test(dataProvider = "Map<IntegerEnum,String>") 71 public void testGetOrDefault(String description, Map<IntegerEnum, String> map) { 72 assertTrue(map.containsKey(KEYS[1]), "expected key missing"); 73 assertSame(map.get(KEYS[1]), map.getOrDefault(KEYS[1], EXTRA_VALUE), "values should match"); 74 assertFalse(map.containsKey(EXTRA_KEY), "expected absent key"); 75 assertSame(map.getOrDefault(EXTRA_KEY, EXTRA_VALUE), EXTRA_VALUE, "value not returned as default"); 76 assertNull(map.getOrDefault(EXTRA_KEY, null), "null not returned as default"); 77 } 78 79 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>") 80 public void testPutIfAbsentNulls(String description, Map<IntegerEnum, String> map) { 81 assertTrue(map.containsKey(null), "null key absent"); 82 assertNull(map.get(null), "value not null"); 83 assertNull(map.putIfAbsent(null, EXTRA_VALUE), "previous not null"); 84 assertTrue(map.containsKey(null), "null key absent"); 85 assertSame(map.get(null), EXTRA_VALUE, "unexpected value"); 86 assertSame(map.putIfAbsent(null, null), EXTRA_VALUE, "previous not expected value"); 87 assertTrue(map.containsKey(null), "null key absent"); 88 assertSame(map.get(null), EXTRA_VALUE, "unexpected value"); 89 assertSame(map.remove(null), EXTRA_VALUE, "removed unexpected value"); 90 91 assertFalse(map.containsKey(null), description + ": key present after remove"); 92 assertNull(map.putIfAbsent(null, null), "previous not null"); 93 assertTrue(map.containsKey(null), "null key absent"); 94 assertNull(map.get(null), "value not null"); 95 assertNull(map.putIfAbsent(null, EXTRA_VALUE), "previous not null"); 96 assertSame(map.get(null), EXTRA_VALUE, "value not expected"); 97 } 98 99 @Test(dataProvider = "R/W Map<IntegerEnum,String>") 100 public void testPutIfAbsent(String description, Map<IntegerEnum, String> map) { 101 assertTrue(map.containsKey(KEYS[1])); 102 Object expected = map.get(KEYS[1]); 103 assertTrue(null == expected || expected == VALUES[1]); 104 assertSame(map.putIfAbsent(KEYS[1], EXTRA_VALUE), expected); 105 assertSame(map.get(KEYS[1]), expected); 106 107 assertFalse(map.containsKey(EXTRA_KEY)); 108 assertSame(map.putIfAbsent(EXTRA_KEY, EXTRA_VALUE), null); 109 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); 110 } 111 112 @Test(dataProvider = "Nulls Map<IntegerEnum,String>") 113 public void testForEach(String description, Map<IntegerEnum, String> map) { 114 IntegerEnum[] EACH_KEY = new IntegerEnum[map.size()]; 115 116 map.forEach((k, v) -> { 117 int idx = (null == k) ? 0 : k.ordinal(); // substitute for index. 118 assertNull(EACH_KEY[idx]); 119 EACH_KEY[idx] = (idx == 0) ? KEYS[0] : k; // substitute for comparison. 120 assertSame(v, map.get(k)); 121 }); 122 123 assertEquals(KEYS, EACH_KEY); 124 } 125 126 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>") 127 public static void testRemoveNulls(String description, Map<IntegerEnum, String> map) { 128 assertTrue(map.containsKey(null), "null key absent"); 129 assertNull(map.get(null), "value not null"); 130 assertFalse(map.remove(null, EXTRA_VALUE), description); 131 assertTrue(map.containsKey(null)); 132 assertNull(map.get(null)); 133 assertTrue(map.remove(null, null)); 134 assertFalse(map.containsKey(null)); 135 assertNull(map.get(null)); 136 assertFalse(map.remove(null, null)); 137 } 138 139 @Test(dataProvider = "R/W Map<IntegerEnum,String>") 140 public static void testRemove(String description, Map<IntegerEnum, String> map) { 141 assertTrue(map.containsKey(KEYS[1])); 142 Object expected = map.get(KEYS[1]); 143 assertTrue(null == expected || expected == VALUES[1]); 144 assertFalse(map.remove(KEYS[1], EXTRA_VALUE), description); 145 assertSame(map.get(KEYS[1]), expected); 146 assertTrue(map.remove(KEYS[1], expected)); 147 assertNull(map.get(KEYS[1])); 148 assertFalse(map.remove(KEYS[1], expected)); 149 150 assertFalse(map.containsKey(EXTRA_KEY)); 151 assertFalse(map.remove(EXTRA_KEY, EXTRA_VALUE)); 152 } 153 154 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>") 155 public void testReplaceKVNulls(String description, Map<IntegerEnum, String> map) { 156 assertTrue(map.containsKey(null), "null key absent"); 157 assertNull(map.get(null), "value not null"); 158 assertSame(map.replace(null, EXTRA_VALUE), null); 159 assertSame(map.get(null), EXTRA_VALUE); 160 } 161 162 @Test(dataProvider = "R/W Map<IntegerEnum,String>") 163 public void testReplaceKV(String description, Map<IntegerEnum, String> map) { 164 assertTrue(map.containsKey(KEYS[1])); 165 Object expected = map.get(KEYS[1]); 166 assertTrue(null == expected || expected == VALUES[1]); 167 assertSame(map.replace(KEYS[1], EXTRA_VALUE), expected); 168 assertSame(map.get(KEYS[1]), EXTRA_VALUE); 169 170 assertFalse(map.containsKey(EXTRA_KEY)); 171 assertNull(map.replace(EXTRA_KEY, EXTRA_VALUE)); 172 assertFalse(map.containsKey(EXTRA_KEY)); 173 assertNull(map.get(EXTRA_KEY)); 174 assertNull(map.put(EXTRA_KEY, EXTRA_VALUE)); 175 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); 176 assertSame(map.replace(EXTRA_KEY, (String)expected), EXTRA_VALUE); 177 assertSame(map.get(EXTRA_KEY), expected); 178 } 179 180 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>") 181 public void testReplaceKVVNulls(String description, Map<IntegerEnum, String> map) { 182 assertTrue(map.containsKey(null), "null key absent"); 183 assertNull(map.get(null), "value not null"); 184 assertFalse(map.replace(null, EXTRA_VALUE, EXTRA_VALUE)); 185 assertNull(map.get(null)); 186 assertTrue(map.replace(null, null, EXTRA_VALUE)); 187 assertSame(map.get(null), EXTRA_VALUE); 188 assertTrue(map.replace(null, EXTRA_VALUE, EXTRA_VALUE)); 189 assertSame(map.get(null), EXTRA_VALUE); 190 } 191 192 @Test(dataProvider = "R/W Map<IntegerEnum,String>") 193 public void testReplaceKVV(String description, Map<IntegerEnum, String> map) { 194 assertTrue(map.containsKey(KEYS[1])); 195 Object expected = map.get(KEYS[1]); 196 assertTrue(null == expected || expected == VALUES[1]); 197 assertFalse(map.replace(KEYS[1], EXTRA_VALUE, EXTRA_VALUE)); 198 assertSame(map.get(KEYS[1]), expected); 199 assertTrue(map.replace(KEYS[1], (String)expected, EXTRA_VALUE)); 200 assertSame(map.get(KEYS[1]), EXTRA_VALUE); 201 assertTrue(map.replace(KEYS[1], EXTRA_VALUE, EXTRA_VALUE)); 202 assertSame(map.get(KEYS[1]), EXTRA_VALUE); 203 204 assertFalse(map.containsKey(EXTRA_KEY)); 205 assertFalse(map.replace(EXTRA_KEY, EXTRA_VALUE, EXTRA_VALUE)); 206 assertFalse(map.containsKey(EXTRA_KEY)); 207 assertNull(map.get(EXTRA_KEY)); 208 assertNull(map.put(EXTRA_KEY, EXTRA_VALUE)); 209 assertTrue(map.containsKey(EXTRA_KEY)); 210 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); 211 assertTrue(map.replace(EXTRA_KEY, EXTRA_VALUE, EXTRA_VALUE)); 212 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); 213 } 214 215 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>") 216 public void testComputeIfAbsentNulls(String description, Map<IntegerEnum, String> map) { 217 assertTrue(map.containsKey(null), "null key absent"); 218 assertNull(map.get(null), "value not null"); 219 assertSame(map.computeIfAbsent(null, (k) -> EXTRA_VALUE), EXTRA_VALUE, description); 220 assertSame(map.get(null), EXTRA_VALUE, description); 221 } 222 223 @Test(dataProvider = "R/W Map<IntegerEnum,String>") 224 public void testComputeIfAbsent(String description, Map<IntegerEnum, String> map) { 225 assertTrue(map.containsKey(KEYS[1])); 226 Object expected = map.get(KEYS[1]); 227 assertTrue(null == expected || expected == VALUES[1], description + String.valueOf(expected)); 228 expected = (null == expected) ? EXTRA_VALUE : expected; 229 assertSame(map.computeIfAbsent(KEYS[1], (k) -> EXTRA_VALUE), expected, description); 230 assertSame(map.get(KEYS[1]), expected, description); 231 232 assertFalse(map.containsKey(EXTRA_KEY)); 233 assertSame(map.computeIfAbsent(EXTRA_KEY, (k) -> EXTRA_VALUE), EXTRA_VALUE); 234 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); 235 } 236 237 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>") 238 public void testComputeIfPresentNulls(String description, Map<IntegerEnum, String> map) { 239 assertTrue(map.containsKey(null)); 240 assertNull(map.get(null)); 241 assertSame(map.computeIfPresent(null, (k, v) -> { 242 fail(); 243 return EXTRA_VALUE; 244 }), null, description); 245 assertTrue(map.containsKey(null)); 246 assertSame(map.get(null), null, description); 247 } 248 249 @Test(dataProvider = "R/W Map<IntegerEnum,String>") 250 public void testComputeIfPresent(String description, Map<IntegerEnum, String> map) { 251 assertTrue(map.containsKey(KEYS[1])); 252 Object value = map.get(KEYS[1]); 253 assertTrue(null == value || value == VALUES[1], description + String.valueOf(value)); 254 Object expected = (null == value) ? null : EXTRA_VALUE; 255 assertSame(map.computeIfPresent(KEYS[1], (k, v) -> { 256 assertSame(v, value); 257 return EXTRA_VALUE; 258 }), expected, description); 259 assertSame(map.get(KEYS[1]), expected, description); 260 261 assertFalse(map.containsKey(EXTRA_KEY)); 262 assertSame(map.computeIfPresent(EXTRA_KEY, (k, v) -> { 263 fail(); 264 return EXTRA_VALUE; 265 }), null); 266 assertFalse(map.containsKey(EXTRA_KEY)); 267 assertSame(map.get(EXTRA_KEY), null); 268 } 269 270 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>") 271 public void testComputeNulls(String description, Map<IntegerEnum, String> map) { 272 assertTrue(map.containsKey(null), "null key absent"); 273 assertNull(map.get(null), "value not null"); 274 assertSame(map.compute(null, (k, v) -> { 275 assertSame(k, null); 276 assertNull(v); 277 return EXTRA_VALUE; 278 }), EXTRA_VALUE, description); 279 assertTrue(map.containsKey(null)); 280 assertSame(map.get(null), EXTRA_VALUE, description); 281 assertSame(map.remove(null), EXTRA_VALUE, "removed value not expected"); 282 assertFalse(map.containsKey(null), "null key present"); 283 assertSame(map.compute(null, (k, v) -> { 284 assertSame(k, null); 285 assertNull(v); 286 return null; 287 }), null, description); 288 } 289 290 @Test(dataProvider = "R/W Map<IntegerEnum,String>") 291 public void testCompute(String description, Map<IntegerEnum, String> map) { 292 assertTrue(map.containsKey(KEYS[1])); 293 Object value = map.get(KEYS[1]); 294 assertTrue(null == value || value == VALUES[1], description + String.valueOf(value)); 295 assertSame(map.compute(KEYS[1], (k, v) -> { 296 assertSame(k, KEYS[1]); 297 assertSame(v, value); 298 return EXTRA_VALUE; 299 }), EXTRA_VALUE, description); 300 assertSame(map.get(KEYS[1]), EXTRA_VALUE, description); 301 assertNull(map.compute(KEYS[1], (k, v) -> { 302 assertSame(v, EXTRA_VALUE); 303 return null; 304 }), description); 305 assertFalse(map.containsKey(KEYS[1])); 306 307 assertFalse(map.containsKey(EXTRA_KEY)); 308 assertSame(map.compute(EXTRA_KEY, (k, v) -> { 309 assertNull(v); 310 return EXTRA_VALUE; 311 }), EXTRA_VALUE); 312 assertTrue(map.containsKey(EXTRA_KEY)); 313 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); 314 } 315 316 317 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>") 318 public void testMergeNulls(String description, Map<IntegerEnum, String> map) { 319 assertTrue(map.containsKey(null), "null key absent"); 320 assertNull(map.get(null), "value not null"); 321 assertSame(map.merge(null, EXTRA_VALUE, (v, vv) -> { 322 assertNull(v); 323 assertSame(vv, EXTRA_VALUE); 324 return vv; 325 }), EXTRA_VALUE, description); 326 assertTrue(map.containsKey(null)); 327 assertSame(map.get(null), EXTRA_VALUE, description); 328 } 329 330 @Test(dataProvider = "R/W Map<IntegerEnum,String>") 331 public void testMerge(String description, Map<IntegerEnum, String> map) { 332 assertTrue(map.containsKey(KEYS[1])); 333 Object value = map.get(KEYS[1]); 334 assertTrue(null == value || value == VALUES[1], description + String.valueOf(value)); 335 assertSame(map.merge(KEYS[1], EXTRA_VALUE, (v, vv) -> { 336 assertSame(v, value); 337 assertSame(vv, EXTRA_VALUE); 338 return vv; 339 }), EXTRA_VALUE, description); 340 assertSame(map.get(KEYS[1]), EXTRA_VALUE, description); 341 assertNull(map.merge(KEYS[1], EXTRA_VALUE, (v, vv) -> { 342 assertSame(v, EXTRA_VALUE); 343 assertSame(vv, EXTRA_VALUE); 344 return null; 345 }), description); 346 assertFalse(map.containsKey(KEYS[1])); 347 348 assertFalse(map.containsKey(EXTRA_KEY)); 349 assertSame(map.merge(EXTRA_KEY, EXTRA_VALUE, (v, vv) -> { 350 assertNull(v); 351 assertSame(vv, EXTRA_VALUE); 352 return EXTRA_VALUE; 353 }), EXTRA_VALUE); 354 assertTrue(map.containsKey(EXTRA_KEY)); 355 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); 356 } 357 358 enum IntegerEnum { 359 360 e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, 361 e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, 362 e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, 363 e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, 364 e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, 365 e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, 366 e60, e61, e62, e63, e64, e65, e66, e67, e68, e69, 367 e70, e71, e72, e73, e74, e75, e76, e77, e78, e79, 368 e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, 369 e90, e91, e92, e93, e94, e95, e96, e97, e98, e99, 370 EXTRA_KEY; 371 public static final int SIZE = values().length; 372 }; 373 private static final int TEST_SIZE = IntegerEnum.SIZE - 1; 374 /** 375 * Realized keys ensure that there is always a hard ref to all test objects. 376 */ 377 private static final IntegerEnum[] KEYS = new IntegerEnum[TEST_SIZE]; 378 /** 379 * Realized values ensure that there is always a hard ref to all test 380 * objects. 381 */ 382 private static final String[] VALUES = new String[TEST_SIZE]; 383 384 static { 385 IntegerEnum[] keys = IntegerEnum.values(); 386 for (int each = 0; each < TEST_SIZE; each++) { 387 KEYS[each] = keys[each]; 388 VALUES[each] = String.valueOf(each); 389 } 390 } 391 private static final IntegerEnum EXTRA_KEY = IntegerEnum.EXTRA_KEY; 392 private static final String EXTRA_VALUE = String.valueOf(TEST_SIZE); 393 394 @DataProvider(name = "Map<IntegerEnum,String>", parallel = true) 395 public static Iterator<Object[]> allNullsMapProvider() { 396 return makeAllMaps().iterator(); 397 } 398 399 @DataProvider(name = "Nulls Map<IntegerEnum,String>", parallel = true) 400 public static Iterator<Object[]> allMapProvider() { 401 return makeRWMaps(true).iterator(); 402 } 403 404 @DataProvider(name = "R/W Map<IntegerEnum,String>", parallel = true) 405 public static Iterator<Object[]> rwMapProvider() { 406 return makeRWMapsNoNulls().iterator(); 407 } 408 409 @DataProvider(name = "R/W Nulls Map<IntegerEnum,String>", parallel = true) 410 public static Iterator<Object[]> rwNullsMapProvider() { 411 return makeRWMaps(true).iterator(); 412 } 413 414 private static Collection<Object[]> makeAllMapsNoNulls() { 415 Collection<Object[]> all = new ArrayList<>(); 416 417 all.addAll(makeRWMaps(false)); 418 all.addAll(makeRWNoNullsMaps()); 419 all.addAll(makeROMaps(false)); 420 421 return all; 422 } 423 424 private static Collection<Object[]> makeRWMapsNoNulls() { 425 Collection<Object[]> all = new ArrayList<>(); 426 427 all.addAll(makeRWMaps(false)); 428 all.addAll(makeRWNoNullsMaps()); 429 430 return all; 431 } 432 433 private static Collection<Object[]> makeAllMaps() { 434 Collection<Object[]> all = new ArrayList<>(); 435 436 all.addAll(makeROMaps(false)); 437 all.addAll(makeRWMaps(false)); 438 all.addAll(makeRWNoNullsMaps()); 439 all.addAll(makeRWMaps(true)); 440 all.addAll(makeROMaps(true)); 441 442 return all; 443 } 444 445 private static Collection<Object[]> makeAllRWMaps() { 446 Collection<Object[]> all = new ArrayList<>(); 447 448 all.addAll(makeRWMaps(false)); 449 all.addAll(makeRWNoNullsMaps()); 450 all.addAll(makeRWMaps(true)); 451 452 return all; 453 } 454 455 private static Collection<Object[]> makeRWMaps(boolean nulls) { 456 return Arrays.asList( 457 new Object[]{"HashMap", makeMap(HashMap::new, nulls)}, 458 new Object[]{"IdentityHashMap", makeMap(IdentityHashMap::new, nulls)}, 459 new Object[]{"LinkedHashMap", makeMap(LinkedHashMap::new, nulls)}, 460 new Object[]{"WeakHashMap", makeMap(WeakHashMap::new, nulls)}, 461 new Object[]{"Collections.checkedMap(HashMap)", Collections.checkedMap(makeMap(HashMap::new, nulls), IntegerEnum.class, String.class)}, 462 new Object[]{"Collections.synchronizedMap(HashMap)", Collections.synchronizedMap(makeMap(HashMap::new, nulls))}, 463 new Object[]{"ExtendsAbstractMap", makeMap(ExtendsAbstractMap::new, nulls)}); 464 } 465 466 private static Collection<Object[]> makeRWNoNullsMaps() { 467 return Arrays.asList( 468 // null hostile 469 new Object[]{"EnumMap", makeMap(() -> new EnumMap(IntegerEnum.class), false)}, 470 new Object[]{"Hashtable", makeMap(Hashtable::new, false)}, 471 new Object[]{"TreeMap", makeMap(TreeMap::new, false)}, 472 new Object[]{"ConcurrentHashMap", makeMap(ConcurrentHashMap::new, false)}, 473 new Object[]{"ConcurrentSkipListMap", makeMap(ConcurrentSkipListMap::new, false)}, 474 new Object[]{"Collections.checkedMap(ConcurrentHashMap)", Collections.checkedMap(makeMap(ConcurrentHashMap::new, false), IntegerEnum.class, String.class)}, 475 new Object[]{"Collections.synchronizedMap(EnumMap)", Collections.synchronizedMap(makeMap(() -> new EnumMap(IntegerEnum.class), false))}, 476 new Object[]{"ImplementsConcurrentMap", makeMap(ImplementsConcurrentMap::new, false)}); 477 } 478 479 private static Collection<Object[]> makeROMaps(boolean nulls) { 480 return Arrays.asList(new Object[][]{ 481 new Object[]{"Collections.unmodifiableMap(HashMap)", Collections.unmodifiableMap(makeMap(HashMap::new, nulls))} 482 }); 483 } 484 485 private static Map<IntegerEnum, String> makeMap(Supplier<Map<IntegerEnum, String>> supplier, boolean nulls) { 486 Map<IntegerEnum, String> result = supplier.get(); 487 488 for (int each = 0; each < TEST_SIZE; each++) { 489 if (nulls) { 490 result.put((each == 0) ? null : KEYS[each], null); 491 } else { 492 result.put(KEYS[each], VALUES[each]); 493 } 494 } 495 496 return result; 497 } 498 499 public interface Thrower<T extends Throwable> { 500 501 public void run() throws T; 502 } 503 504 public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable) { 505 assertThrows(thrower, throwable, null); 506 } 507 508 public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable, String message) { 509 Throwable result; 510 try { 511 thrower.run(); 512 result = null; 513 } catch (Throwable caught) { 514 result = caught; 515 } 516 517 assertInstance(result, throwable, 518 (null != message) 519 ? message 520 : "Failed to throw " + throwable.getCanonicalName()); 521 } 522 523 public static <T> void assertInstance(T actual, Class<? extends T> expected) { 524 assertInstance(expected.isInstance(actual), null); 525 } 526 527 public static <T> void assertInstance(T actual, Class<? extends T> expected, String message) { 528 assertTrue(expected.isInstance(actual), message); 529 } 530 531 /** 532 * A simple mutable map implementation that provides only default 533 * implementations of all methods. ie. none of the Map interface default 534 * methods have overridden implementations. 535 * 536 * @param <K> Type of keys 537 * @param <V> Type of values 538 */ 539 public static class ExtendsAbstractMap<M extends Map<K,V>, K, V> extends AbstractMap<K, V> { 540 541 protected final M map; 542 543 public ExtendsAbstractMap() { this( (M) new HashMap<K,V>()); } 544 545 protected ExtendsAbstractMap(M map) { this.map = map; } 546 547 public Set<Map.Entry<K, V>> entrySet() { 548 return new AbstractSet<Map.Entry<K, V>>() { 549 public int size() { 550 return map.size(); 551 } 552 553 public Iterator<Map.Entry<K,V>> iterator() { 554 final Iterator<Map.Entry<K,V>> source = map.entrySet().iterator(); 555 return new Iterator<Map.Entry<K,V>>() { 556 public boolean hasNext() { return source.hasNext(); } 557 public Map.Entry<K,V> next() { return source.next(); } 558 public void remove() { source.remove(); } 559 }; 560 } 561 562 public boolean add(Map.Entry<K,V> e) { 563 return map.entrySet().add(e); 564 } 565 }; 566 } 567 568 public V put(K key, V value) { 569 return map.put(key, value); 570 } 571 } 572 573 /** 574 * A simple mutable concurrent map implementation that provides only default 575 * implementations of all methods. ie. none of the ConcurrentMap interface 576 * default methods have overridden implementations. 577 * 578 * @param <K> Type of keys 579 * @param <V> Type of values 580 */ 581 public static class ImplementsConcurrentMap<K, V> extends ExtendsAbstractMap<ConcurrentMap<K,V>, K, V> implements ConcurrentMap<K,V> { 582 public ImplementsConcurrentMap() { super(new ConcurrentHashMap<K,V>()); } 583 584 // ConcurrentMap reabstracts these methods 585 586 public V replace(K k, V v) { return map.replace(k, v); }; 587 588 public boolean replace(K k, V v, V vv) { return map.replace(k, v, vv); }; 589 590 public boolean remove(Object k, Object v) { return map.remove(k, v); } 591 592 public V putIfAbsent(K k, V v) { return map.putIfAbsent(k, v); } 593 } 594 }