ConcurrentMap
指定putIfAbsent()
的返回值为:
与指定键关联的先前值,如果没有键的映射,则返回null。 (如果实现支持空值,则null返回还可以指示映射先前将null与键关联。)
并提供以下代码作为示例。
if (!map.containsKey(key))
return map.put(key, value);
else
return map.get(key);
}
问题是,如果只有在给定密钥的地图中不存在条目时才调用map.put(key, value)
,那么如何才能存在先前的值?在我看来,如果在调用putIfAbsent()
之前没有包含给定键的条目,它将始终返回当前值或null。
答案 0 :(得分:3)
请考虑以下几行:
ConcurrentMap<String, String> map = new ConcurrentHashMap<>();
System.out.println(map.putIfAbsent("key", "value1")); // prints null (no previous value)
System.out.println(map.putIfAbsent("key", "value2")); // prints "value1"
在第一次调用putIfAbsent
时,没有与关键字key
相关联的值。因此,putIfAbsent
将返回null
。
在第二次调用时,putIfAbsent
将返回上一个映射,即value1
,并且该值不会在地图中更新,因为它已经存在。
虽然putIfAbsent
确实会返回当前值(如果有该键的映射),但此处引入“先前值”的概念与Map.put
的定义一致,返回先前的值。引用它的Javadoc:
与key关联的上一个值,如果没有key的映射,则返回null。
答案 1 :(得分:2)
我认为此前的单词只是为了强调该值在调用之前已经在地图中。它并不是一个很好的选择,因为它表明地图中可能存在一个与前一个不同的新值,而实际上并不存在。但是代码示例完全解释了该方法的作用,因此我不担心它。
答案 2 :(得分:0)
如果我们讨论任何并发数据结构,我们需要记住,这些数据结构是为并发执行而设计的。
putIfAbsent
表示如果Thread1
和Thread2
尝试使用相同的key
添加一些数据,只有一个Thread
会执行此操作。