Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use put() or putIfAbsent() after using getOrDefault()?

Java8 introduced those nice methods getOrDefault() and putIfAbsent(), allowing to write code like:

Map<Foo, List<Bar>> itemsByFoo = ...
List<Bar> bars = itemsByFoo.getOrDefault(key, new ArrayList<>());
bars.add(someNewBar);

Now I am wondering if there are good factual reasons to either do:

itemsByFoo.put(key, bars);

or

itemsByFoo.putIfAbsent(key, bars);

Both would work:

  • option 1 might do a lot of unnecessary "put" calls when adding elements to lists happens often
  • option2 might do a lot of unnecessary "containsKey" calls when adding new entries for new keys is dominant

SO: are the good reasons to go for option 1 or option 2 "always"?

like image 519
GhostCat Avatar asked Aug 02 '17 11:08

GhostCat


People also ask

What is putIfAbsent in Java?

The putIfAbsent(Key, value) method of Hashtable class which allows to map a value to a given key if given key is not associated with a value or mapped to null. A null value is returned if such key-value set is already present in the HashMap.

What is HashMap in Java?

HashMap<K, V> is a part of Java's collection since Java 1.2. This class is found in java. util package. It provides the basic implementation of the Map interface of Java. It stores the data in (Key, Value) pairs, and you can access them by an index of another type (e.g. an Integer).


1 Answers

getOrDefault is suitable if you want to use a stand-in for an absent value without modifying the map. If you want to add a new value for absent keys, you can do it right in one operation.

List<Bar> bars = itemsByFoo.computeIfAbsent(key, x -> new ArrayList<>());
bars.add(someNewBar);

or even

itemsByFoo.computeIfAbsent(key, x -> new ArrayList<>()).add(someNewBar);

In the best case, when being overridden by the Map implementation, like with HashMap, this will bear a single hash lookup only.

Not that putIfAbsent only bears two lookups when using the default implementation, but, of course, most Map implementations will provide a single lookup implementation for it. Still, the combination of getOrDefault and putIfAbsent would still bear two lookups in the best case, whereas an optimized computeIfAbsent does only one.

like image 108
Holger Avatar answered Sep 19 '22 21:09

Holger