Why HashMap merge is doing null check on value. HashMap supports null key and null values.So can some one please tell why null check on merge is required?
@Override
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
if (value == null)
throw new NullPointerException();
if (remappingFunction == null)
throw new NullPointerException();
Due to this I am unable to use Collectors.toMap(Function.identity(), this::get)
to collect values in a Map
To make sure key exists you should use HashMap#containsKey(key) function. Once key exists you may use HashMap#get(key) to get the value and compare it to null. Show activity on this post.
HashMap is similar to HashTable, but it is unsynchronized. It allows to store the null keys as well, but there should be only one null key object and there can be any number of null values. This class makes no guarantees as to the order of the map.
Now you must be wondering why HashTable doesn't allow null and HashMap do? The answer is simple. In order to successfully store and retrieve objects from a HashTable, the objects used as keys must implement the hashCode method and the equals method. Since null is not an object, it can't implement these methods.
The Java HashMap merge() method inserts the specified key/value mapping to the hashmap if the specified key is already not present. If the specified key is already associated with a value, the method replaces the old value with the result of the specified function.
The behavior is mandated by the Map.merge
contract:
Throws:
…
NullPointerException - if the specified key is null and this map does not support null keys or the value or remappingFunction is null
Note that using Map.merge
for Collectors.toMap
without a merge function is an implementation detail; it not only disallows null
values, it does not provide the desired behavior for reporting duplicate keys, the Java 8 implementation wrongly reports one of the two values as key when there are duplicate keys.
In Java 9, the implementation has been completely rewritten, it does not use Map.merge
anymore. But the new implementation is behavioral compatible, now having code explicitly throwing when the value is null
. So the behavior of Collectors.toMap
not accepting null
values has been fixed in the code and is not an artifact of using Map.merge
anymore. (Still speaking of the toMap
collector without a merge function only.)
Unfortunately, the documentation does not tell.
Because internally for Collectors.toMap
, Map#merge
is used - you can't really do anything about it. Using the static Collectors.toMap
is not an option (which by the way is documented to throw a NullPointerException
).
But spinning a custom collector to be able to do what you want (which you have not shown) is not that complicated, here is an example:
Map<Integer, Integer> result = Arrays.asList(null, 1, 2, 3)
.stream()
.collect(
HashMap::new,
(map, i) -> {
map.put(i, i);
},
HashMap::putAll);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With