map and null values

Brian Goetz brian.goetz at
Thu Jan 3 09:10:57 PST 2013

You are correct.  But you want a choice that is not on the menu.

The choices were:

1.  These are methods from ConcurrentMap.  The ConcurrentMap semantics 
are hostile to null.  We cannot have these methods both on Map and 
ConcurrentMap with different semantics, so we cannot put these methods 
on Map.  End of story.

2.  We can pull these down to Maps that are willing to be consistent 
with the null behavior of ConcurrentMap.  It's already a stretch to do 
this because of atomicity / exactly-once invocation concerns, but we 
managed to work this out with careful spec'ing (thanks Doug!), and the 
added benefit of Map users getting these methods is worth the stretch.

We chose (2), which offers enhanced behavior to a broader range of 
users.  Would you really prefer we had chosen (1)?

On 1/3/2013 11:37 AM, Peter Levart wrote:
> On 01/03/2013 04:46 PM, Brian Goetz wrote:
>> Another way of saying this is: this is easy for non-concurrent maps,
>> but basically impossible for concurrent maps.  Since these methods are
>> being ported down from ConcurrentMap to Map, bending over backwards to
>> accomodate uses that won't work anyway in their intended domain is a
>> complete waste of energy.
> The methods: remove(key, value), replace(key, oldValue, newValue),
> replace(key, value) & putIfAbsent(key, value) are perfectly usable also
> in non-concurrent and non-atomic domain, since they provide an
> opportunity for optimization in various implementations. Currently there
> is no way to achieve their semantics on plain Map (like j.u.HashMap)
> without doing two lookups.
> That's also true for computeIfAbsent and friends but the benefit is
> questionable, since another lookup might be faster then the construction
> of a lambda object.
> Regards, Peter
>> On 1/3/2013 10:40 AM, Doug Lea wrote:
>>> On 01/03/13 09:57, Peter Levart wrote:
>>>> And if there is a way to provide a single default
>>>> implementation in j.u.Map that satisfies both ConcurrentMap
>>>> implementations that
>>>> don't allow nulls and plain Map implementations that allow nulls,
>>>> why not
>>>> provide it?
>>> Feel free to try. The main constraint is that, to apply to
>>> possibly-concurrent maps, the  four new function-accepting
>>> methods must be expressed only in terms of putIfAbsent,
>>> replace, and/or two-argument remove. While I haven't tried
>>> to prove this, I believe that all ways of doing it encounter
>>> the null ambiguity.
>>> -Doug

More information about the lambda-dev mailing list