map and null values
Brian Goetz
brian.goetz at oracle.com
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
this.
>>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