使用getOrDefault()之后应该使用put()还是putIfAbsent()?


问题内容

Java8引入了这些不错的方法getOrDefault()putIfAbsent(),从而允许编写如下代码:

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

现在,我想知道是否有充分的事实理由可以这样做:

itemsByFoo.put(key, bars);

要么

itemsByFoo.putIfAbsent(key, bars);

两者都可以工作:

  • 将元素添加到列表 时,选项1可能会进行很多不必要的“ put”调用
  • 选项2可能做了很多不必要的“的containsKey”呼叫时 对新的密钥添加新条目 是主导

SO:“总是”选择选项1或选项2的充分理由是吗?


问题答案:

getOrDefault如果您想对替代值使用缺席值而不修改地图,则适用。如果要为不存在的键添加新值,则可以一次完成操作。

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

甚至

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

最好的情况是,当Map实现被实现覆盖时(如)HashMap,此操作将仅进行一次哈希查找。

putIfAbsent使用该default实现时,不仅要进行两次查找,而且,当然,大多数Map实现将为此提供一个查找实现。不过,组合getOrDefaultputIfAbsent仍然将承担在最好的情况下两个查找,而优化的computeIfAbsent确实只有一个。