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:
parent
851fd0447e
commit
ca9e74c63d
@ -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 &&
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user