A suggestion: Map.checkAndGet

David Holmes david.holmes at oracle.com
Tue Oct 30 22:52:25 PDT 2012


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