vigna / fastutil

fastutil extends the Java™ Collections Framework by providing type-specific maps, sets, lists and queues.
Apache License 2.0
1.74k stars 194 forks source link

putIfAbsent should replace a null value #280

Open ben-manes opened 1 year ago

ben-manes commented 1 year ago

This was shown in a recent Java Collections Puzzlers. The JavaDoc for Map.putIfAbsent states the following.

If the specified key is not already associated with a value (or is mapped to {@code null}) associates it with the given value and returns {@code null}, else returns the current value.

@Test
public void putIfAbsent_nullExistingValue() {
  var map = new Object2ObjectOpenHashMap<Object, Object>();
  map.put("a", null);
  map.putIfAbsent("a", "b");
  assertThat(map).containsEntry("a", "b");
}
FAILED: Test.putIfAbsent_nullExistingValue
key is present but with a different value
value of: map.get(a)
expected: b
but was : null
map was : {a=>null}

The computeIfAbsent method has similar wording and fails in this scenario.

I have requested that this peculiarity of the api be added to Guava's testlib.

vigna commented 1 year ago

I see, the code is currently shared between primitive types and object types. Probably adding a conditional check for null would solve the problem.

vigna commented 1 year ago

(Provided that all that stuff is entirely unnatural and I'm perfectly sure everybody is carefully avoiding relying on those dark corners of the API.)