Ответ 1
ConcurrentMap.putIfAbscent возвращает предыдущее значение, связанное с указанным ключом, или null, если не было сопоставления для ключа. У вас не было значения, связанного с "ключом 3". Все правильные
Следующая программа печатает 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");
}
}
Может ли кто-нибудь помочь мне понять поведение?
ConcurrentMap.putIfAbscent возвращает предыдущее значение, связанное с указанным ключом, или null, если не было сопоставления для ключа. У вас не было значения, связанного с "ключом 3". Все правильные
putIfAbsent()
возвращает предыдущее значение, связанное с указанным ключом, или null
, если для ключа не было сопоставления, и потому что key 3
нет на карте, поэтому он возвращает null
.
Вы добавили на карту key 1
и key 2
, но key 3
не связаны ни с каким значением. Итак, вы получаете null
. Карта key 3
с некоторым значением и putIfAbsent()
вернет предыдущее значение, связанное с этим ключом.
Например, если в карте уже содержится key 3
, связанной со значением A
key 3 ---> A
Тогда при вызове map.putIfAbsent("key 3","B")
вернется A
Проблема в том, что по определению putIfAbsent возвращает старое значение, а не новое значение (старое значение для отсутствующего всегда равно null). Используйте computeIfAbsent - это вернет вам новое значение.
private static String get(final String key) {
return map.computeIfAbsent(key, s -> "value 3");
}
Это часто задаваемый вопрос, который, возможно, предполагает, что это поведение неинтуитивно. Возможно, путаница возникает из-за того, как dict.setdefault() работает на python и других языках. Возвращая тот же объект, который вы только что положили, помогает вырезать несколько строк кода.
Рассмотрим:
if (map.contains(value)){
obj = map.get(key);
}
else{
obj = new Object();
}
против
obj = map.putIfAbsent(key, new Object());
Прочитайте документацию ConcurrentHashMap.putIfAbsent
:
Возвращает:
предыдущее значение, связанное с указанным ключом, илиnull
, если не было сопоставления для ключа
Поскольку не было предыдущего значения для ключа "key 3"
, он возвращает null
.
В javadoc:
возвращает предыдущее значение, связанное с указанным ключом, или null, если не было сопоставления для ключа
Если вы посмотрите на документацию, в нем говорится
Возвращает: предыдущее значение, связанное с указанным ключом, или null, если не было сопоставления для ключа
В вашем случае никакое значение ранее не было связано с ключом, следовательно NULL