Search code examples
javajava.util.concurrentconcurrenthashmap

What is the previous value mentioned in ConcurrentMap.putIfAbsent()


ConcurrentMap specifies the return value of putIfAbsent() as:

the previous value associated with the specified key, or null if there was no mapping for the key. (A null return can also indicate that the map previously associated null with the key, if the implementation supports null values.)

And gives the following code as an example of this.

if (!map.containsKey(key))
    return map.put(key, value);
else
    return map.get(key);
}

The question is how can there ever be a previous value if map.put(key, value) is only invoked when no entry exists in the map with the given key ? It seems to me that it would always return the current value or null if no entry with the given key existed prior to the call to putIfAbsent().


Solution

  • Consider the following lines:

    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"
    

    On the first call to putIfAbsent, there is no value associated with the key key. Therefore, putIfAbsent will return null as documented.

    On the second call, putIfAbsent will return the previous mapping, which is value1 and the value will not be updated in the map because it already exists.

    While it is true that putIfAbsent will always return the current value if there is a mapping for that key, the notion of "previous value" is introduced here to be consistent with the definition of Map.put, which returns the previous value. Quoting its Javadoc:

    the previous value associated with key, or null if there was no mapping for key.