Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HashMap null check in Merge Operation

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

like image 319
Paul Erric Avatar asked Feb 27 '18 06:02

Paul Erric


People also ask

How do you do null check for HashMap in java?

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.

What if key is null in HashMap?

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.

What will happen when we insert null in HashMap?

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.

What does the merge () method on map do?

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.


2 Answers

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.

like image 190
Holger Avatar answered Sep 28 '22 02:09

Holger


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);
like image 41
Eugene Avatar answered Sep 28 '22 01:09

Eugene