8024331: j.u.Map.computeIfPresent() default/nondefault implementations don't throw NPE if the remappingFunction is null and the key is absent

Explicitly check for null remappingFunction parameter.

Reviewed-by: mduigou, forax, psandoz
This commit is contained in:
Brian Burkhalter 2013-09-20 15:12:05 -07:00 committed by Brian Burkhalter
parent 851fd0447e
commit ca9e74c63d
3 changed files with 66 additions and 1 deletions

View File

@ -1132,6 +1132,8 @@ public class HashMap<K,V> extends AbstractMap<K,V>
public V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
if (remappingFunction == null)
throw new NullPointerException();
Node<K,V> e; V oldValue;
int hash = hash(key);
if ((e = getNode(hash, key)) != null &&

View File

@ -934,6 +934,7 @@ public interface Map<K,V> {
*/
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
V v, newValue;
return ((v = get(key)) == null &&
(newValue = mappingFunction.apply(key)) != null &&
@ -992,6 +993,7 @@ public interface Map<K,V> {
*/
default V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue;
while ((oldValue = get(key)) != null) {
V newValue = remappingFunction.apply(key, oldValue);
@ -1068,6 +1070,7 @@ public interface Map<K,V> {
*/
default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue = get(key);
for (;;) {
V newValue = remappingFunction.apply(key, oldValue);
@ -1174,6 +1177,7 @@ public interface Map<K,V> {
*/
default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue = get(key);
for (;;) {
if (oldValue != null) {

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8010122 8004518
* @bug 8010122 8004518 8024331
* @summary Test Map default methods
* @author Mike Duigou
* @run testng Defaults
@ -288,6 +288,21 @@ public class Defaults {
assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
}
@Test(expectedExceptions = {NullPointerException.class})
public void testComputeIfAbsentNPEHashMap() {
Object value = new HashMap().computeIfAbsent(KEYS[1], null);
}
@Test(expectedExceptions = {NullPointerException.class})
public void testComputeIfAbsentNPEHashtable() {
Object value = new Hashtable().computeIfAbsent(KEYS[1], null);
}
@Test(expectedExceptions = {NullPointerException.class})
public void testComputeIfAbsentNPETreeMap() {
Object value = new TreeMap().computeIfAbsent(KEYS[1], null);
}
@Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
public void testComputeIfPresentNulls(String description, Map<IntegerEnum, String> map) {
assertTrue(map.containsKey(null), description + ": null key absent");
@ -328,6 +343,21 @@ public class Defaults {
assertSame(map.get(EXTRA_KEY), null);
}
@Test(expectedExceptions = {NullPointerException.class})
public void testComputeIfPresentNPEHashMap() {
Object value = new HashMap().computeIfPresent(KEYS[1], null);
}
@Test(expectedExceptions = {NullPointerException.class})
public void testComputeIfPresentNPEHashtable() {
Object value = new Hashtable().computeIfPresent(KEYS[1], null);
}
@Test(expectedExceptions = {NullPointerException.class})
public void testComputeIfPresentNPETreeMap() {
Object value = new TreeMap().computeIfPresent(KEYS[1], null);
}
@Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
public void testComputeNulls(String description, Map<IntegerEnum, String> map) {
assertTrue(map.containsKey(null), "null key absent");
@ -414,6 +444,20 @@ public class Defaults {
assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
}
@Test(expectedExceptions = {NullPointerException.class})
public void testComputeNPEHashMap() {
Object value = new HashMap().compute(KEYS[1], null);
}
@Test(expectedExceptions = {NullPointerException.class})
public void testComputeNPEHashtable() {
Object value = new Hashtable().compute(KEYS[1], null);
}
@Test(expectedExceptions = {NullPointerException.class})
public void testComputeNPETreeMap() {
Object value = new TreeMap().compute(KEYS[1], null);
}
@Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
public void testMergeNulls(String description, Map<IntegerEnum, String> map) {
@ -456,6 +500,21 @@ public class Defaults {
assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
}
@Test(expectedExceptions = {NullPointerException.class})
public void testMergeNPEHashMap() {
Object value = new HashMap().merge(KEYS[1], VALUES[1], null);
}
@Test(expectedExceptions = {NullPointerException.class})
public void testMergeNPEHashtable() {
Object value = new Hashtable().merge(KEYS[1], VALUES[1], null);
}
@Test(expectedExceptions = {NullPointerException.class})
public void testMergeNPETreeMap() {
Object value = new TreeMap().merge(KEYS[1], VALUES[1], null);
}
enum IntegerEnum {
e0, e1, e2, e3, e4, e5, e6, e7, e8, e9,