map and null values

Brian Goetz brian.goetz at
Wed Jan 2 09:01:07 PST 2013

The way to think about this is that these methods are transplants down 
from ConcurrentMap to Map, where the Map versions have non-atomic 
default implementations (suitable for within-thread use.)  In concurrent 
maps, null values are not supported; instead a null value is interpreted 
as "no mapping."  The semantics of the new methods are consistent with 

>>From looking on Map::computeIfAbsent and Map::computeIfPresent
> it seems that it was greed that get(key)==null  and ! containsKey(key) are
> the same (or in other words null values are not interesting)
> It is quite sad for some of us, And it is not consistent with methods
> Map::putIfAbsent and Map::replace

Consistency here is an impossible goal, since there are already 
inconsistencies present in how the JDK classes handle null, so any new 
functionality will be inconsistent with something already.  So we have 
to pick which of the existing strategies we prefer to extend.  The 
alternative is never adding anything.  Surely you don't want that.

> Also the assumption the null values are not legal is so strong, that the
> implementation of replace::
>   default boolean replace(K key, V oldValue, V newValue) {
>          if (*!containsKey(key) || !get(key).equals(oldValue)*)
>              return false;
>          put(key, newValue);
>          return true;
>      }
> throws NPE exception in the example below:
> mss.put("null", null);
> mss.replace("null", null, "null");

Note that many existing Map implementations throw NPE when you try and 
put a null key or value into it anyway.

More information about the lambda-dev mailing list