Java8 introduced those nice methods getOrDefault() and putIfAbsent(), allowing to write code like:
Map> itemsByFoo = ...
List 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"?
解决方案
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 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.