Why does Map.of not allow null keys and values?

Once upon a time an engineer with years of experience encounter something so basic he doesn’t understand why he didn’t encounter it sooner.

Note the java map you’re looking for.

This week we had a strange error in our log stating that should have a null values in a map.

After some digging in the service where that log was found, it seems to be not coming from us…

But why can’t a map have a null values. It’s easy to understand why we can have a null key value but why can’t the value be null?

Well it make sense, why keep an empty record in a key when you could just remove the key and it’s not in the map it means it’s null. That free up the map to make it more efficient.

If you straight up initialize a map with Map.of() and include a null value, it will throw a null pointer exception. However, if you do it with a HashMap it will work fine. You can even have null key that way. Most modern implementation of map won’t allow null in their keys or values.

If you want a better explaination checkout this stackoverflow answer: Why does Map.of not allow null keys and values?

Here the TL;DR:

Allowing null in collections is by now seen as a design error. This has a variety of reasons. A good one is usability, where the most prominent trouble maker is Map::get. If it returns null, it is unclear whether the key is missing or the value was null. Generally speaking, collections that are guaranteed null free are easier to use. Implementation-wise, they also require less special casing, making the code easier to maintain and more performant.

Null elements, keys, and values will be disallowed. (No recently introduced collections have supported nulls.) In addition, prohibiting nulls offers opportunities for a more compact internal representation, faster access, and fewer special cases.

Since HashMap was already out in the wild when this was slowly discovered, it was too late to change it without breaking existing code but most recent implementations of those interfaces (e.g. ConcurrentHashMap) do not allow null anymore and the new collections for the factory methods are no exception.

So disallowing null had some technical reason but it was also done to improve the robustness of the code using the created collections.