A suggestion: Map.checkAndGet

David Holmes david.holmes at oracle.com
Wed Oct 31 04:44:15 PDT 2012


Boaz pointed out to me that my suggestion assumes Maps with no null values.

David

On 31/10/2012 3:52 PM, David Holmes wrote:
> On 31/10/2012 1:25 AM, Boaz Nahum wrote:
>> The pattern
>> map.containsKey(k) ? map.get() : othervAlue
>> (walks on tree twice)
>>
>> repeats itself so many times, as in Mappers:
>>
>>    public static<T, U>   Mapper<T, U>   forMap(Map<? super T, ? extends U>   map,
>> U defaultValue) {
>>           Objects.requireNonNull(map);
>>
>>           return t ->   map.containsKey(t) ? map.get(t) : defaultValue;
>
> The problem is with this ternary expression ...
>
>>    }
>>
>>
>> Now that we have 'default methods', we can add to Map:
>>
>> NullableOptional<V>   checkAndget(K key) default {
>>
>>           if (containsKey(key)) {
>>               return new NullableOptional<>(get(key));
>>           } else {
>>               return NullableOptional.empty();
>>           }
>>       }
>>
>> **and** implement it in Map implementation in such way that will walk on
>> tree only once.
>> (Assume creating instance of NullableOptional is more  efficient )
>>
>> forMap becomes:
>>
>> public static<T, U>   Mapper<T, U>   forMap(MyMap<? super T, ? extends U>   map,
>> U defaultValue) {
>>           Objects.requireNonNull(map);
>>
>>
>>           return t ->   {
>>               NullableOptional<? extends U>   o = map.checkAndget(t);
>>               return o.isPresent() ? o.get() : defaultValue;
>>               //return o.orElse(defaultValue);
>>           };
>>       }
>
> So why do you need checkAndGet if you can just do something like:
>
> return t ->  { U o = map.get(t);
>                 return o != NULL ? o : defaultValue;
> };
>
> The problem lies in how the ternary expression was used, not through any
> deficiency in Map. Unfortunately we need to introduce a temporary
> variable in many situations where we use (or want to use) a ternary
> expression. I cringe every time I see code of the form:
>
> foo() ? foo() : bar();
>
> what is needed for ?: is a way to refer to the first expression such
> that you can use it as the result, without reevaluating or having to
> store in a temporary. But that's not a discussion for lambda-dev.
>
> David
>
>


More information about the lambda-dev mailing list