Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between putIfAbsent and computeIfAbsent in Java 8 Map ?

Tags:

java

java-8

Reading an interesting articles the guys claims that the difference between the two function are:

Both functions aspire to add an element if the specified Key is not already present in Map.

putIfAbsent adds an element with the specified Value whereas computeIfAbsent adds an element with the value computed using the Key. http://www.buggybread.com/2014/10/java-8-difference-between-map.html

And

We’ve seen that putIfAbsent removes the imperative way of having to define the if-statement, but what if fetching the Java articles is really hurting our performance?

To optimise this, we don’t want to fetch the articles until we’re really sure we need them — meaning we need to know if the key is absent before fetching the articles. http://www.deadcoderising.com/2017-02-14-java-8-declarative-ways-of-modifying-a-map-using-compute-merge-and-replace/

I didn't ready understand what are the differences can you please elaborate more on these two functions ?

like image 564
Adelin Avatar asked Jan 10 '18 09:01

Adelin


People also ask

What does the computeIfAbsent () method on map do?

The computeIfAbsent(Key, Function) method of HashMap class is used to compute value for a given key using the given mapping function, if key is not already associated with a value (or is mapped to null) and enter that computed value in Hashmap else null.

What is putIfAbsent in map?

The Java HashMap putIfAbsent() method inserts the specified key/value mapping to the hashmap if the specified key is already not present in the hashmap. The syntax of the putIfAbsent() method is: hashmap.putIfAbsent(K key, V value) Here, hashmap is an object of the HashMap class.


2 Answers

Difference #1

computeIfAbsent takes a mapping function, that is called to obtain the value if the key is missing.

putIfAbsent takes the value directly.

If the value is expensive to obtain, then putIfAbsent wastes that if the key already exists.

A common "expensive" value is e.g. new ArrayList<>() for when you're creating a Map<K, List<V>>, where creating a new list when the key already exists (which then discards the new list) generates unnecessary garbage.


Difference #2

computeIfAbsent returns "the current (existing or computed) value associated with the specified key, or null if the computed value is null".

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

So, if the key already exists, they return the same thing, but if the key is missing, computeIfAbsent returns the computed value, while putIfAbsent return null.


Difference #3

Both method define "absent" as key missing or existing value is null, but:

computeIfAbsent will not put a null value if the key is absent.

putIfAbsent will put the value if the key is absent, even if the value is null.

It makes no difference for future calls to computeIfAbsent, putIfAbsent, and get calls, but it does make a difference to calls like getOrDefault and containsKey.

like image 129
Andreas Avatar answered Oct 12 '22 13:10

Andreas


Suppose you have a Map<String,ValueClass>.

map.putIfAbsent("key", new ValueClass()); 

will create a ValueClass instance anyway, even if the "key" key is already in the Map. This would just create an unnecessary instance.

On the other hand

map.computeIfAbsent("key", k -> new ValueClass()); 

will only create a ValueClass instance if the "key" key is not already in the Map (or is mapped to a null value).

Therefore computeIfAbsent is more efficient.

putIfAbsent is equivalent to:

ValueClass value = new ValueClass(); if (map.get("key") == null) {     map.put("key",value); } 

while computeIfAbsent is equivalent to:

if (map.get("key") == null) {     map.put("key",new ValueClass()); } 

Another small difference between the two methods is that computeIfAbsent will not put a null value for an absent key. putIfAbsent will.

like image 20
Eran Avatar answered Oct 12 '22 12:10

Eran