This question has already been answered. I took a little time to understand ("expensive operation doesn't need to be performed in case the map already contains a value for the specified key in computeIfAbsent")
I am putting my understanding here. Hope this will be helpful to others:
putIfAbsent()
behaves simply as put()
when map already contains the value for the specified key. putIfAbsent()
only checks whether key is null or not.
If it is not null then it returns the value and then map fetch that value again.
However, in computeIfAbsent()
there is null check for both key and value. During null check for value, if it is not null then existing value from the map object
is assigned to newValue and it is returned. That's why there is no need to again fetch the value as existing value from map is re-used.
Refer to following program for reference:
public class MapTest1 {
public static final String AJAY_DEVGAN = "Ajay Devgn";
public static final String AUTOBIOGRAPHY = "Autobiography";
public static void main(String[] args) {
MapTest1 mt = new MapTest1();
mt.testPutCompute();
}
private void testPutCompute() {
Map<String, List<String>> movies = getMovieObject();
System.out.println("\nCalling putIfAbsent method.....");
//System.out.println(movies.get(AJAY_DEVGAN));
//movies.put(AJAY_DEVGAN, getAjayDevgnMovies());
movies.putIfAbsent(AJAY_DEVGAN, getAjayDevgnMovies());
System.out.println("\nCalling computeIfAbsent method......");
//System.out.println(movies.get(AUTOBIOGRAPHY));
movies.computeIfAbsent(AUTOBIOGRAPHY, t -> getAutobiographyMovies());
}
private Map<String, List<String>> getMovieObject() {
Map<String, List<String>> movies = new HashMap<>();
movies.put(AJAY_DEVGAN, getAjayDevgnMovies());
movies.put(AUTOBIOGRAPHY, getAutobiographyMovies());
System.out.println(movies);
return movies;
}
private List<String> getAutobiographyMovies() {
System.out.println("Getting autobiography movies");
List<String> list = new ArrayList<>();
list.add("M.S. Dhoni - The Untold Story");
list.add("Sachin: A Billion Dreams");
return list;
}
private List<String> getAjayDevgnMovies() {
System.out.println("Getting Ajay Devgn Movies");
List<String> ajayDevgnMovies = new ArrayList<>();
ajayDevgnMovies.add("Jigar");
ajayDevgnMovies.add("Pyar To Hona Hi Tha");
return ajayDevgnMovies;
}
}
Refer to following code for putIfAbsent()
and computeIfAbsent()
from interface Map.class
public interface Map<K,V> {
.....
default V putIfAbsent(K key, V value) {
V v = get(key);
if (v == null) {
v = put(key, value);
}
return v;
}
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
V v;
if ((v = get(key)) == null) {
V newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
put(key, newValue);
return newValue;
}
}
return v;
}
.........
}