Map.getOrDefault(Object,Supplier<V>) override
    John Rose 
    john.r.rose at oracle.com
       
    Thu Apr 18 15:37:19 PDT 2013
    
    
  
On Apr 18, 2013, at 2:45 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> Feature creep alert!
> 
> getOrDefault barely, and I mean barely, carried its weight.
Putting on my lambdaphile hat again...
I agree that getOrDefault is weak.  I suggest (what may already have been suggested?) the Supplier<T> version *instead* of the plain T version of getOrDefault.
Then you could use Suppliers.constant(x) or Suppliers.alwaysThrow(IllegalArgumentException.class) or ()->(your code here).
  int n = myToIntMap.getOrDefault(k, ()->Integer.MIN_VALUE);  // was .getOrDefault(k, Integer.MIN_VALUE)
  String s = myMap.getOrDefault(k, ()->"none");  // was .getOrDefault(k, "none")
  String t = myMap.getOrDefault(k, ()->{throw new IllegalArgumentException();});
The current code for Functions.forMap has this comment which would be addressed by the more powerful getOrDefault:
      // XXX mduigou it would be nice to optimise this to a single operation
— John
P.S.  Thinking about making this play with Optional led me to two bad options, which I'll float in case they inspire something better.
#1 We could lean a little harder on the type Map.Entry.  Replace getOrDefault with:
  class Map<K,V> {
      Entry<K,V> getAsOptional(K key) { ... }
   }
Then:
  Optional<Map.Entry<K,V>> x = myMap.getAsOptional(myKey);
  V y = (x.isPresent() ? x.get().getValue() : z);
#2 An extractor-based API would be powerful enough but too hard to use.  I mean something like:
   class Map<K,V> {
      R getOrElse(K key, Function<? super V,? extends R> ifPresent, Supplier<? extends R> ifAbsent) { ... }
   }
Then:
  Optional<V> x = myMap.getOrElse(myKey, Optional::of, Optional::empty);
  V y = (x.isPresent() ? x.get() : z);
    
    
More information about the lambda-dev
mailing list