ConcurrentHashMap putIfAbsent() возвращает null

Следующая программа печатает 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");
    }
}

Может ли кто-нибудь помочь мне понять поведение?

Ответ 1

ConcurrentMap.putIfAbscent возвращает предыдущее значение, связанное с указанным ключом, или null, если не было сопоставления для ключа. У вас не было значения, связанного с "ключом 3". Все правильные

Ответ 2

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

Ответ 3

Проблема в том, что по определению putIfAbsent возвращает старое значение, а не новое значение (старое значение для отсутствующего всегда равно null). Используйте computeIfAbsent - это вернет вам новое значение.

private static String get(final String key) {
    return map.computeIfAbsent(key, s -> "value 3");
}

Ответ 4

Это часто задаваемый вопрос, который, возможно, предполагает, что это поведение неинтуитивно. Возможно, путаница возникает из-за того, как dict.setdefault() работает на python и других языках. Возвращая тот же объект, который вы только что положили, помогает вырезать несколько строк кода.

Рассмотрим:

if (map.contains(value)){
    obj = map.get(key);
}
else{
    obj = new Object();
}

против

obj = map.putIfAbsent(key, new Object());

Ответ 5

Прочитайте документацию ConcurrentHashMap.putIfAbsent:

Возвращает:
    предыдущее значение, связанное с указанным ключом, или null, если не было сопоставления для ключа

Поскольку не было предыдущего значения для ключа "key 3", он возвращает null.

Ответ 6

В javadoc:

возвращает предыдущее значение, связанное с указанным ключом, или null, если не было сопоставления для ключа

Ответ 7

Если вы посмотрите на документацию, в нем говорится

Возвращает: предыдущее значение, связанное с указанным ключом, или null, если не было сопоставления для ключа

В вашем случае никакое значение ранее не было связано с ключом, следовательно NULL