Navigation Menu

Skip to content

Commit

Permalink
8259622: TreeMap.computeIfAbsent deviates from spec
Browse files Browse the repository at this point in the history
Reviewed-by: smarks
  • Loading branch information
amaembo committed Jan 15, 2021
1 parent d701bab commit 2c8e337
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
14 changes: 11 additions & 3 deletions src/java.base/share/classes/java/util/TreeMap.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -575,8 +575,12 @@ public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction
t = t.left;
else if (cmp > 0)
t = t.right;
else
else {
if (t.value == null) {
t.value = callMappingFunctionWithCheck(key, mappingFunction);
}
return t.value;
}
} while (t != null);
} else {
Objects.requireNonNull(key);
Expand All @@ -589,8 +593,12 @@ else if (cmp > 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
else {
if (t.value == null) {
t.value = callMappingFunctionWithCheck(key, mappingFunction);
}
return t.value;
}
} while (t != null);
}
newValue = callMappingFunctionWithCheck(key, mappingFunction);
Expand Down
16 changes: 15 additions & 1 deletion test/jdk/java/util/Map/InPlaceOpsCollisions.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -257,6 +257,20 @@ void testComputeIfAbsentNull(String desc, Supplier<Map<Object, Object>> ms, Obje
testComputeIfAbsent(map, desc, keys, (k) -> null);
}

@Test(dataProvider = "nullValueFriendlyMaps")
void testComputeIfAbsentOverwriteNull(String desc, Supplier<Map<Object, Object>> ms) {
Map<Object, Object> map = ms.get();
map.put("key", null);
assertEquals(map.size(), 1, desc + ": size != 1");
assertTrue(map.containsKey("key"), desc + ": does not have key");
assertNull(map.get("key"), desc + ": value is not null");
Object result = map.computeIfAbsent("key", k -> "value"); // must rewrite
assertEquals(result, "value", desc + ": computeIfAbsent result is not 'value'");
assertEquals(map.size(), 1, desc + ": size != 1");
assertTrue(map.containsKey("key"), desc + ": does not have key");
assertEquals(map.get("key"), "value", desc + ": value is not 'value'");
}

private static <T> void testComputeIfPresent(Map<T, T> map, String desc, T[] keys,
BiFunction<T, T, T> mappingFunction) {
// remove a third of the keys
Expand Down

1 comment on commit 2c8e337

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.