阅读一篇有趣的文章,这些人声称这两个功能的区别在于:
如果Map中没有指定的Key,则两个函数都希望添加元素.
putIfAbsent添加具有指定Value的元素,而computeIfAbsent添加具有使用Key计算的值的元素. http://www.buggybread.com/2014/10/java-8-difference-between-map.html
和
我们已经看到putIfAbsent删除了必须定义if语句的必要方法,但是如果获取Java文章真的会损害我们的性能呢?
为了优化这一点,我们不想在我们确定需要它们之前获取文章 - 这意味着在获取文章之前我们需要知道密钥是否缺失. http://www.deadcoderising.com/2017-02-14-java-8-declarative-ways-of-modifying-a-map-using-compute-merge-and-replace/
我还没准备好了解哪些差异可以请你详细说明这两个功能?
And*_*eas 96
差异#1
computeIfAbsent 采用映射函数,如果缺少键,则调用该函数以获取值.
putIfAbsent 直接取值.
如果获取的值很昂贵,那么putIfAbsent如果密钥已经存在则会浪费.
一个常见的"昂贵"值是例如new ArrayList<>()当你创建一个时Map<K, List<V>>,当密钥已经存在时创建一个新列表(然后丢弃新列表)会产生不必要的垃圾.
差异#2
computeIfAbsent 返回"与指定键关联的当前(现有或已计算)值,如果计算值为null,则返回null".
putIfAbsent 返回"与指定键关联的先前值,如果没有键的映射,则返回null".
因此,如果密钥已经存在,它们将返回相同的内容,但如果密钥丢失,则computeIfAbsent返回计算值,同时putIfAbsent返回null.
差异#3
两种方法都将"缺席"定义为关键缺失或现有值为null,但是:
computeIfAbsent 如果密钥不存在,则不会设置空值.
putIfAbsent 如果密钥不存在,将放置该值,即使该值为null.
这使得对未来没有什么区别调用computeIfAbsent,putIfAbsent以及get调用,但它确实像呼叫差异getOrDefault和containsKey.
Era*_*ran 46
假设你有一个Map<String,ValueClass>.
map.putIfAbsent("key", new ValueClass());
Run Code Online (Sandbox Code Playgroud)
ValueClass无论如何都会创建一个实例,即使"key"键已经在Map.这只会创建一个不必要的实例.
另一方面
map.computeIfAbsent("key", k -> new ValueClass());
Run Code Online (Sandbox Code Playgroud)
ValueClass如果"key"键不在Map(或映射到某个null值),则只会创建一个实例.
因此computeIfAbsent效率更高.
putIfAbsent 相当于:
ValueClass value = new ValueClass();
if (map.get("key") == null) {
map.put("key",value);
}
Run Code Online (Sandbox Code Playgroud)
虽然computeIfAbsent相当于:
if (map.get("key") == null) {
map.put("key",new ValueClass());
}
Run Code Online (Sandbox Code Playgroud)
两种方法之间的另一个小差异是computeIfAbsent不会null为缺席密钥设置值.putIfAbsent将.
您可以通过仔细查看方法签名来理解差异:
putIfAbsent 接受一个键和值,如果映射中没有该键的值,则将该值放入映射中。computeIfAbsent需要一把钥匙和一个Function. 如果映射中没有该键的值,则调用该函数来创建该值,然后将该值放入映射中。如果您已经拥有该值,请使用putIfAbsent.
如果您还没有该值并且创建该值是一项代价高昂的操作(例如,必须在数据库中查找该值),则使用computeIfAbsent,这样就不需要执行代价高昂的操作,以防万一映射已包含指定键的值。
也许默认实现可以澄清一点....
default V putIfAbsent?(K key, V value)
对于此映射,默认实现等效于:
V v = map.get(key);
if (v == null)
v = map.put(key, value);
return v;
Run Code Online (Sandbox Code Playgroud)
另一方面:
default V computeIfAbsent?(K key,
Function<? super K,? extends V> mappingFunction)
Run Code Online (Sandbox Code Playgroud)
相当于:
if (map.get(key) == null) {
V newValue = mappingFunction.apply(key);
if (newValue != null)
map.put(key, newValue);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
30740 次 |
| 最近记录: |