Gho*_*ica 12 java collections dictionary java-8
Java8介绍那些漂亮的方法getOrDefault()和putIfAbsent(),让写代码,如:
Map<Foo, List<Bar>> itemsByFoo = ...
List<Bar> bars = itemsByFoo.getOrDefault(key, new ArrayList<>());
bars.add(someNewBar);
Run Code Online (Sandbox Code Playgroud)
现在我想知道是否有很好的事实理由:
itemsByFoo.put(key, bars);
Run Code Online (Sandbox Code Playgroud)
要么
itemsByFoo.putIfAbsent(key, bars);
Run Code Online (Sandbox Code Playgroud)
两者都有效:
那么:选择1或选项2"总是"的充分理由是什么?
Hol*_*ger 20
getOrDefault如果您想在不修改地图的情况下使用替代值来获取缺席值,则此选项是合适的.如果要为缺席键添加新值,可以在一次操作中正确执行.
List<Bar> bars = itemsByFoo.computeIfAbsent(key, x -> new ArrayList<>());
bars.add(someNewBar);
Run Code Online (Sandbox Code Playgroud)
甚至
itemsByFoo.computeIfAbsent(key, x -> new ArrayList<>()).add(someNewBar);
Run Code Online (Sandbox Code Playgroud)
在最好的情况下,当被Map实现覆盖时,就像使用一样HashMap,这将只承担一次哈希查找.
putIfAbsent在使用default实现时,并不是只有两次查找,但是,当然,大多数Map实现都会为它提供单个查找实现.不过,组合getOrDefault和putIfAbsent仍然将承担在最好的情况下两个查找,而优化的computeIfAbsent确实只有一个.
一个重要的一点computeIfAbsent是它需要一个Function只有在Key缺席时才能执行,我们需要一个默认值Value.
而getOrDefault需要默认Value本身,已经计算过.在这种情况下,Value我们需要的默认值是a new ArrayList<Bar>(),它具有在堆上分配新对象的副作用.
我们希望推迟这样做,直到我们确定它还key没有itemsByFoo.否则我们会产生不必要的垃圾gc来收集.