Java ConcurrentHashMap putIfAbsent()返回null
以下程序正在打印Java ConcurrentHashMap putIfAbsent()返回null,java,concurrenthashmap,Java,Concurrenthashmap,以下程序正在打印null。我不明白为什么 public class ConcurrentHashMapTest { public static final ConcurrentMap<String, String> map = new ConcurrentHashMap<>(5, 0.9f, 2); public static void main(String[] args) { map.putIfAbsent("key 1&q
null
。我不明白为什么
public class ConcurrentHashMapTest {
public static final ConcurrentMap<String, String> map = new ConcurrentHashMap<>(5, 0.9f, 2);
public static void main(String[] args) {
map.putIfAbsent("key 1", "value 1");
map.putIfAbsent("key 2", "value 2");
String value = get("key 3");
System.out.println("value for key 3 --> " + value);
}
private static String get(final String key) {
return map.putIfAbsent(key, "value 3");
}
}
公共类ConcurrentHashMapTest{
公共静态最终ConcurrentMap=新ConcurrentHashMap(5,0.9f,2);
公共静态void main(字符串[]args){
putIfAbsent地图(“键1”、“值1”);
putIfAbsent地图(“键2”、“值2”);
字符串值=获取(“键3”);
System.out.println(“键3的值-->”+值);
}
私有静态字符串get(最终字符串密钥){
返回映射putIfAbsent(键,“值3”);
}
}
有人能帮我理解这个行为吗?ConcurrentMap.putIfAbsent返回与指定键关联的上一个值,如果没有该键的映射,则返回null。您没有与“键3”关联的值。完全正确 注意:这不仅适用于
ConcurrentMap
,而且适用于Map
的所有实现返回与指定键关联的先前值,或者如果键没有映射,则返回null
,因为键3
不在映射中,所以返回null
您已经在地图中添加了键1
和键2
,但是键3
与任何值都没有关联。所以你得到了一个null
。使用某个值映射键3
,并且putIfAbsent()
将返回与该键关联的上一个值
例如,如果映射已经包含与值A
关联的键3
key 3 ---> A
然后调用
map.putIfAbsent(“键3”,“B”)
将返回A
请阅读以下文档:
key 3 ---> A
返回:与指定键关联的上一个值,如果该键没有映射,则为
null
由于键“键3”
没有以前的值,它返回null
它在javadoc中:
返回与指定键关联的上一个值,如果该键没有映射,则返回null
如果你看一下文档,它会说 返回:
与指定键关联的上一个值,或 如果密钥没有映射,则为null
在您的情况下,以前没有与键关联的值,因此
NULL
这是一个常见问题,这可能表明此行为是不直观的。可能是由于dict.setdefault()在python和其他语言中的工作方式造成了混淆。返回刚才放置的同一对象有助于减少几行代码
考虑:
if (map.contains(value)){
obj = map.get(key);
}
else{
obj = new Object();
}
与:
obj = map.putIfAbsent(key, new Object());
问题在于,根据定义,putIfAbsent返回旧值,而不是新值(缺席的旧值总是空的)。使用computeIfAbsent-这将为您返回新值
private static String get(final String key) {
return map.computeIfAbsent(key, s -> "value 3");
}
可以使用
merge
函数返回当前映射值。如果键已经存在,则以下命令将返回当前非空值;如果映射不存在或值为null
,则返回给定的新值
私有静态字符串获取(最终字符串键){
返回map.merge(键,“值3”,(oldVal,newVal)->oldVal);
}
或一般而言:
private T get(最终字符串键,T值){
返回map.merge(键,值,(oldVal,newVal)->oldVal);
}
当您不喜欢使用computeIfAbsent
时,这可能很有用,因为到computeIfAbsent
的映射函数可能会引发异常,并且您也不想执行以下操作:
map.putIfAbsent(键、值);
返回map.get(key);
所有答案都是正确的,只需补充一点
如果指定的键尚未与值关联(或
映射到null)将其与给定值关联并返回null,
else返回当前值
公共V值(K键,V值){
返回putVal(key,value,true);}
键保留在表中。可以通过调用get方法来检索该值,方法的键等于put之前的原始键。如果在表中找不到键,则返回null。您期望的行为是什么,为什么?对于引号,您应该使用
,而不是代码格式。是的,我忘了…:)已经有一段时间没有响应了,它不允许异常抛出,太糟糕了。和其他lambda一样。因此,要么使用@Skillythrows,要么使用rethrow exception作为RuntimeException。@Skillythrows
是邪恶的。选中的异常比@Skillythrows:)更邪恶。这是一个原子操作吗?如中所示,映射能否在contains和get之间更改?