test/java/util/Map/Defaults.java

Print this page
rev 8056 : 8024331: j.u.Map.computeIfPresent() default/nondefault implementations don't throw NPE if the remappingFunction is null and the key is absent
Summary: Explicitly check for null remappingFunction parameter.
Reviewed-by: TBD
Contributed-by: Brian Burkhalter <brian.burkhalter@oracle.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 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.HashSet;
  40 import java.util.Hashtable;
  41 import java.util.IdentityHashMap;
  42 import java.util.Iterator;
  43 import java.util.LinkedHashMap;
  44 import java.util.Map;
  45 import java.util.TreeMap;
  46 import java.util.Set;


 271         assertTrue(map.containsKey(null), "null key absent");
 272         assertNull(map.get(null), "value not null");
 273         assertSame(map.computeIfAbsent(null, (k) -> EXTRA_VALUE), EXTRA_VALUE, description);
 274         assertSame(map.get(null), EXTRA_VALUE, description);
 275     }
 276 
 277     @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
 278     public void testComputeIfAbsent(String description, Map<IntegerEnum, String> map) {
 279         assertTrue(map.containsKey(KEYS[1]));
 280         Object expected = map.get(KEYS[1]);
 281         assertTrue(null == expected || expected == VALUES[1], description + String.valueOf(expected));
 282         expected = (null == expected) ? EXTRA_VALUE : expected;
 283         assertSame(map.computeIfAbsent(KEYS[1], (k) -> EXTRA_VALUE), expected, description);
 284         assertSame(map.get(KEYS[1]), expected, description);
 285 
 286         assertFalse(map.containsKey(EXTRA_KEY));
 287         assertSame(map.computeIfAbsent(EXTRA_KEY, (k) -> EXTRA_VALUE), EXTRA_VALUE);
 288         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 289     }
 290 















 291     @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
 292     public void testComputeIfPresentNulls(String description, Map<IntegerEnum, String> map) {
 293         assertTrue(map.containsKey(null), description + ": null key absent");
 294         assertNull(map.get(null), description + ": value not null");
 295         assertSame(map.computeIfPresent(null, (k, v) -> {
 296             fail(description + ": null value is not deemed present");
 297             return EXTRA_VALUE;
 298         }), null, description);
 299         assertTrue(map.containsKey(null));
 300         assertNull(map.get(null), description);
 301         assertNull(map.remove(EXTRA_KEY), description + ": unexpected mapping");
 302         assertNull(map.put(EXTRA_KEY, null), description + ": unexpected value");
 303         assertSame(map.computeIfPresent(EXTRA_KEY, (k, v) -> {
 304             fail(description + ": null value is not deemed present");
 305             return EXTRA_VALUE;
 306         }), null, description);
 307         assertNull(map.get(EXTRA_KEY), description + ": null mapping gone");
 308     }
 309 
 310     @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
 311     public void testComputeIfPresent(String description, Map<IntegerEnum, String> map) {
 312         assertTrue(map.containsKey(KEYS[1]));
 313         Object value = map.get(KEYS[1]);
 314         assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
 315         Object expected = (null == value) ? null : EXTRA_VALUE;
 316         assertSame(map.computeIfPresent(KEYS[1], (k, v) -> {
 317             assertSame(v, value);
 318             return EXTRA_VALUE;
 319         }), expected, description);
 320         assertSame(map.get(KEYS[1]), expected, description);
 321 
 322         assertFalse(map.containsKey(EXTRA_KEY));
 323         assertSame(map.computeIfPresent(EXTRA_KEY, (k, v) -> {
 324             fail();
 325             return EXTRA_VALUE;
 326         }), null);
 327         assertFalse(map.containsKey(EXTRA_KEY));
 328         assertSame(map.get(EXTRA_KEY), null);
 329     }
 330 















 331     @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
 332     public void testComputeNulls(String description, Map<IntegerEnum, String> map) {
 333         assertTrue(map.containsKey(null), "null key absent");
 334         assertNull(map.get(null), "value not null");
 335         assertSame(map.compute(null, (k, v) -> {
 336             assertNull(k);
 337             assertNull(v);
 338             return null;
 339         }), null, description);
 340         assertFalse(map.containsKey(null), description + ": null key present.");
 341         assertSame(map.compute(null, (k, v) -> {
 342             assertSame(k, null);
 343             assertNull(v);
 344             return EXTRA_VALUE;
 345         }), EXTRA_VALUE, description);
 346         assertTrue(map.containsKey(null));
 347         assertSame(map.get(null), EXTRA_VALUE, description);
 348         assertSame(map.remove(null), EXTRA_VALUE, description + ": removed value not expected");
 349         // no mapping before and after
 350         assertFalse(map.containsKey(null), description + ": null key present");


 397             assertSame(k, KEYS[1]);
 398             assertSame(v, value);
 399             return EXTRA_VALUE;
 400         }), EXTRA_VALUE, description);
 401         assertSame(map.get(KEYS[1]), EXTRA_VALUE, description);
 402         assertNull(map.compute(KEYS[1], (k, v) -> {
 403             assertSame(v, EXTRA_VALUE);
 404             return null;
 405         }), description);
 406         assertFalse(map.containsKey(KEYS[1]));
 407 
 408         assertFalse(map.containsKey(EXTRA_KEY));
 409         assertSame(map.compute(EXTRA_KEY, (k, v) -> {
 410             assertNull(v);
 411             return EXTRA_VALUE;
 412         }), EXTRA_VALUE);
 413         assertTrue(map.containsKey(EXTRA_KEY));
 414         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 415     }
 416 














 417 
 418     @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
 419     public void testMergeNulls(String description, Map<IntegerEnum, String> map) {
 420         assertTrue(map.containsKey(null), "null key absent");
 421         assertNull(map.get(null), "value not null");
 422         assertSame(map.merge(null, EXTRA_VALUE, (v, vv) -> {
 423             assertNull(v);
 424             assertSame(vv, EXTRA_VALUE);
 425             return vv;
 426         }), EXTRA_VALUE, description);
 427         assertTrue(map.containsKey(null));
 428         assertSame(map.get(null), EXTRA_VALUE, description);
 429     }
 430 
 431     @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
 432     public void testMerge(String description, Map<IntegerEnum, String> map) {
 433         assertTrue(map.containsKey(KEYS[1]));
 434         Object value = map.get(KEYS[1]);
 435         assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
 436         assertSame(map.merge(KEYS[1], EXTRA_VALUE, (v, vv) -> {


 439             return vv;
 440         }), EXTRA_VALUE, description);
 441         assertSame(map.get(KEYS[1]), EXTRA_VALUE, description);
 442         assertNull(map.merge(KEYS[1], EXTRA_VALUE, (v, vv) -> {
 443             assertSame(v, EXTRA_VALUE);
 444             assertSame(vv, EXTRA_VALUE);
 445             return null;
 446         }), description);
 447         assertFalse(map.containsKey(KEYS[1]));
 448 
 449         assertFalse(map.containsKey(EXTRA_KEY));
 450         assertSame(map.merge(EXTRA_KEY, EXTRA_VALUE, (v, vv) -> {
 451             assertNull(v);
 452             assertSame(vv, EXTRA_VALUE);
 453             return EXTRA_VALUE;
 454         }), EXTRA_VALUE);
 455         assertTrue(map.containsKey(EXTRA_KEY));
 456         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 457     }
 458 















 459     enum IntegerEnum {
 460 
 461         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9,
 462         e10, e11, e12, e13, e14, e15, e16, e17, e18, e19,
 463         e20, e21, e22, e23, e24, e25, e26, e27, e28, e29,
 464         e30, e31, e32, e33, e34, e35, e36, e37, e38, e39,
 465         e40, e41, e42, e43, e44, e45, e46, e47, e48, e49,
 466         e50, e51, e52, e53, e54, e55, e56, e57, e58, e59,
 467         e60, e61, e62, e63, e64, e65, e66, e67, e68, e69,
 468         e70, e71, e72, e73, e74, e75, e76, e77, e78, e79,
 469         e80, e81, e82, e83, e84, e85, e86, e87, e88, e89,
 470         e90, e91, e92, e93, e94, e95, e96, e97, e98, e99,
 471         EXTRA_KEY;
 472         public static final int SIZE = values().length;
 473     };
 474     private static final int TEST_SIZE = IntegerEnum.SIZE - 1;
 475     /**
 476      * Realized keys ensure that there is always a hard ref to all test objects.
 477      */
 478     private static final IntegerEnum[] KEYS = new IntegerEnum[TEST_SIZE];




   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 8024331
  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.HashSet;
  40 import java.util.Hashtable;
  41 import java.util.IdentityHashMap;
  42 import java.util.Iterator;
  43 import java.util.LinkedHashMap;
  44 import java.util.Map;
  45 import java.util.TreeMap;
  46 import java.util.Set;


 271         assertTrue(map.containsKey(null), "null key absent");
 272         assertNull(map.get(null), "value not null");
 273         assertSame(map.computeIfAbsent(null, (k) -> EXTRA_VALUE), EXTRA_VALUE, description);
 274         assertSame(map.get(null), EXTRA_VALUE, description);
 275     }
 276 
 277     @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
 278     public void testComputeIfAbsent(String description, Map<IntegerEnum, String> map) {
 279         assertTrue(map.containsKey(KEYS[1]));
 280         Object expected = map.get(KEYS[1]);
 281         assertTrue(null == expected || expected == VALUES[1], description + String.valueOf(expected));
 282         expected = (null == expected) ? EXTRA_VALUE : expected;
 283         assertSame(map.computeIfAbsent(KEYS[1], (k) -> EXTRA_VALUE), expected, description);
 284         assertSame(map.get(KEYS[1]), expected, description);
 285 
 286         assertFalse(map.containsKey(EXTRA_KEY));
 287         assertSame(map.computeIfAbsent(EXTRA_KEY, (k) -> EXTRA_VALUE), EXTRA_VALUE);
 288         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 289     }
 290 
 291     @Test(expectedExceptions = {NullPointerException.class})
 292     public void testComputeIfAbsentNPEHashMap() {
 293         Object value = new HashMap().computeIfAbsent(KEYS[1], null);
 294     }
 295 
 296     @Test(expectedExceptions = {NullPointerException.class})
 297     public void testComputeIfAbsentNPEHashtable() {
 298         Object value = new Hashtable().computeIfAbsent(KEYS[1], null);
 299     }
 300 
 301     @Test(expectedExceptions = {NullPointerException.class})
 302     public void testComputeIfAbsentNPETreeMap() {
 303         Object value = new TreeMap().computeIfAbsent(KEYS[1], null);
 304     }
 305 
 306     @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
 307     public void testComputeIfPresentNulls(String description, Map<IntegerEnum, String> map) {
 308         assertTrue(map.containsKey(null), description + ": null key absent");
 309         assertNull(map.get(null), description + ": value not null");
 310         assertSame(map.computeIfPresent(null, (k, v) -> {
 311             fail(description + ": null value is not deemed present");
 312             return EXTRA_VALUE;
 313         }), null, description);
 314         assertTrue(map.containsKey(null));
 315         assertNull(map.get(null), description);
 316         assertNull(map.remove(EXTRA_KEY), description + ": unexpected mapping");
 317         assertNull(map.put(EXTRA_KEY, null), description + ": unexpected value");
 318         assertSame(map.computeIfPresent(EXTRA_KEY, (k, v) -> {
 319             fail(description + ": null value is not deemed present");
 320             return EXTRA_VALUE;
 321         }), null, description);
 322         assertNull(map.get(EXTRA_KEY), description + ": null mapping gone");
 323     }
 324 
 325     @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
 326     public void testComputeIfPresent(String description, Map<IntegerEnum, String> map) {
 327         assertTrue(map.containsKey(KEYS[1]));
 328         Object value = map.get(KEYS[1]);
 329         assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
 330         Object expected = (null == value) ? null : EXTRA_VALUE;
 331         assertSame(map.computeIfPresent(KEYS[1], (k, v) -> {
 332             assertSame(v, value);
 333             return EXTRA_VALUE;
 334         }), expected, description);
 335         assertSame(map.get(KEYS[1]), expected, description);
 336 
 337         assertFalse(map.containsKey(EXTRA_KEY));
 338         assertSame(map.computeIfPresent(EXTRA_KEY, (k, v) -> {
 339             fail();
 340             return EXTRA_VALUE;
 341         }), null);
 342         assertFalse(map.containsKey(EXTRA_KEY));
 343         assertSame(map.get(EXTRA_KEY), null);
 344     }
 345 
 346     @Test(expectedExceptions = {NullPointerException.class})
 347     public void testComputeIfPresentNPEHashMap() {
 348         Object value = new HashMap().computeIfPresent(KEYS[1], null);
 349     }
 350 
 351     @Test(expectedExceptions = {NullPointerException.class})
 352     public void testComputeIfPresentNPEHashtable() {
 353         Object value = new Hashtable().computeIfPresent(KEYS[1], null);
 354     }
 355 
 356     @Test(expectedExceptions = {NullPointerException.class})
 357     public void testComputeIfPresentNPETreeMap() {
 358         Object value = new TreeMap().computeIfPresent(KEYS[1], null);
 359     }
 360 
 361     @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
 362     public void testComputeNulls(String description, Map<IntegerEnum, String> map) {
 363         assertTrue(map.containsKey(null), "null key absent");
 364         assertNull(map.get(null), "value not null");
 365         assertSame(map.compute(null, (k, v) -> {
 366             assertNull(k);
 367             assertNull(v);
 368             return null;
 369         }), null, description);
 370         assertFalse(map.containsKey(null), description + ": null key present.");
 371         assertSame(map.compute(null, (k, v) -> {
 372             assertSame(k, null);
 373             assertNull(v);
 374             return EXTRA_VALUE;
 375         }), EXTRA_VALUE, description);
 376         assertTrue(map.containsKey(null));
 377         assertSame(map.get(null), EXTRA_VALUE, description);
 378         assertSame(map.remove(null), EXTRA_VALUE, description + ": removed value not expected");
 379         // no mapping before and after
 380         assertFalse(map.containsKey(null), description + ": null key present");


 427             assertSame(k, KEYS[1]);
 428             assertSame(v, value);
 429             return EXTRA_VALUE;
 430         }), EXTRA_VALUE, description);
 431         assertSame(map.get(KEYS[1]), EXTRA_VALUE, description);
 432         assertNull(map.compute(KEYS[1], (k, v) -> {
 433             assertSame(v, EXTRA_VALUE);
 434             return null;
 435         }), description);
 436         assertFalse(map.containsKey(KEYS[1]));
 437 
 438         assertFalse(map.containsKey(EXTRA_KEY));
 439         assertSame(map.compute(EXTRA_KEY, (k, v) -> {
 440             assertNull(v);
 441             return EXTRA_VALUE;
 442         }), EXTRA_VALUE);
 443         assertTrue(map.containsKey(EXTRA_KEY));
 444         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 445     }
 446 
 447     @Test(expectedExceptions = {NullPointerException.class})
 448     public void testComputeNPEHashMap() {
 449         Object value = new HashMap().compute(KEYS[1], null);
 450     }
 451 
 452     @Test(expectedExceptions = {NullPointerException.class})
 453     public void testComputeNPEHashtable() {
 454         Object value = new Hashtable().compute(KEYS[1], null);
 455     }
 456 
 457     @Test(expectedExceptions = {NullPointerException.class})
 458     public void testComputeNPETreeMap() {
 459         Object value = new TreeMap().compute(KEYS[1], null);
 460     }
 461 
 462     @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
 463     public void testMergeNulls(String description, Map<IntegerEnum, String> map) {
 464         assertTrue(map.containsKey(null), "null key absent");
 465         assertNull(map.get(null), "value not null");
 466         assertSame(map.merge(null, EXTRA_VALUE, (v, vv) -> {
 467             assertNull(v);
 468             assertSame(vv, EXTRA_VALUE);
 469             return vv;
 470         }), EXTRA_VALUE, description);
 471         assertTrue(map.containsKey(null));
 472         assertSame(map.get(null), EXTRA_VALUE, description);
 473     }
 474 
 475     @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
 476     public void testMerge(String description, Map<IntegerEnum, String> map) {
 477         assertTrue(map.containsKey(KEYS[1]));
 478         Object value = map.get(KEYS[1]);
 479         assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
 480         assertSame(map.merge(KEYS[1], EXTRA_VALUE, (v, vv) -> {


 483             return vv;
 484         }), EXTRA_VALUE, description);
 485         assertSame(map.get(KEYS[1]), EXTRA_VALUE, description);
 486         assertNull(map.merge(KEYS[1], EXTRA_VALUE, (v, vv) -> {
 487             assertSame(v, EXTRA_VALUE);
 488             assertSame(vv, EXTRA_VALUE);
 489             return null;
 490         }), description);
 491         assertFalse(map.containsKey(KEYS[1]));
 492 
 493         assertFalse(map.containsKey(EXTRA_KEY));
 494         assertSame(map.merge(EXTRA_KEY, EXTRA_VALUE, (v, vv) -> {
 495             assertNull(v);
 496             assertSame(vv, EXTRA_VALUE);
 497             return EXTRA_VALUE;
 498         }), EXTRA_VALUE);
 499         assertTrue(map.containsKey(EXTRA_KEY));
 500         assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
 501     }
 502 
 503     @Test(expectedExceptions = {NullPointerException.class})
 504     public void testMergeNPEHashMap() {
 505         Object value = new HashMap().merge(KEYS[1], VALUES[1], null);
 506     }
 507 
 508     @Test(expectedExceptions = {NullPointerException.class})
 509     public void testMergeNPEHashtable() {
 510         Object value = new Hashtable().merge(KEYS[1], VALUES[1], null);
 511     }
 512 
 513     @Test(expectedExceptions = {NullPointerException.class})
 514     public void testMergeNPETreeMap() {
 515         Object value = new TreeMap().merge(KEYS[1], VALUES[1], null);
 516     }
 517 
 518     enum IntegerEnum {
 519 
 520         e0, e1, e2, e3, e4, e5, e6, e7, e8, e9,
 521         e10, e11, e12, e13, e14, e15, e16, e17, e18, e19,
 522         e20, e21, e22, e23, e24, e25, e26, e27, e28, e29,
 523         e30, e31, e32, e33, e34, e35, e36, e37, e38, e39,
 524         e40, e41, e42, e43, e44, e45, e46, e47, e48, e49,
 525         e50, e51, e52, e53, e54, e55, e56, e57, e58, e59,
 526         e60, e61, e62, e63, e64, e65, e66, e67, e68, e69,
 527         e70, e71, e72, e73, e74, e75, e76, e77, e78, e79,
 528         e80, e81, e82, e83, e84, e85, e86, e87, e88, e89,
 529         e90, e91, e92, e93, e94, e95, e96, e97, e98, e99,
 530         EXTRA_KEY;
 531         public static final int SIZE = values().length;
 532     };
 533     private static final int TEST_SIZE = IntegerEnum.SIZE - 1;
 534     /**
 535      * Realized keys ensure that there is always a hard ref to all test objects.
 536      */
 537     private static final IntegerEnum[] KEYS = new IntegerEnum[TEST_SIZE];