Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does java.util.Map's getOrDefault() work?

Tags:

java

I noticed that if I do map.getOrDefault("key1", new Object()), even if object is present for key1 in the map, new Object() is created. Though it is not returned by the method but it still creates it. For example,

public class Empl {     private int id;     private String name;      public Empl(String name) {         // TODO Auto-generated constructor stub         System.out.println(name);         this.name = name;     }     @Override     public String toString() {         // TODO Auto-generated method stub         return name+id;     } } 

running following,

Map<String, Empl> map = new HashMap<String, Empl>(); Empl imp = new Empl("timon"); map.put("1", imp); System.out.println(map.getOrDefault("1", new Empl("dumnba"))); 

gives this output:

timon dumnba timon0 

Shouldn't the default object be created only if it is not there in the map ? What is the reason if not ?

like image 629
Manoj Suthar Avatar asked May 02 '17 11:05

Manoj Suthar


People also ask

How does getOrDefault work in Java?

The getOrDefault(Object key, V defaultValue) method of Map interface, implemented by HashMap class is used to get the value mapped with specified key. If no value is mapped with the provided key then the default value is returned.

How does a HashMap work internally?

HashMap in java use it's inner class Node<K,V> for storing mappings. HashMap works on hashing algorithm and uses hashCode() and equals() method on key for get and put operations. HashMap use singly linked list to store elements, these are called bins or buckets.

How do I retrieve a value from a map?

HashMap. get() method of HashMap class is used to retrieve or fetch the value mapped by a particular key mentioned in the parameter. It returns NULL when the map contains no such mapping for the key.


2 Answers

Shouldn't the default object be created only if it is not there in the map ?

How could that be the case? This call:

map.getOrDefault("1", new Empl("dumnba")) 

is equivalent to:

String arg0 = "1"; Empl arg1 = new Empl("dumnba"); map.getOrDefault(arg0, arg1); 

In other words, all arguments are evaluated before being passed to the method.

You could potentially use computeIfAbsent instead, but that will modify the map if the key was absent, which you may not want:

System.out.println(map.computeIfAbsent("1", k -> new Empl("dumnba"))); 
like image 76
Jon Skeet Avatar answered Oct 01 '22 17:10

Jon Skeet


All the arguments to a function are evaluated before the function is executed. Java needs to evaluate new Empl("dumnba") so it can pass the result into getOrDefault. It can't know before getOrDefault is called that one of the arguments is not going to be required.

If you want to provide a default that is not computed unless needed, you can use computeIfAbsent. For this, you pass in a function, and that function is only executed if the default value is required.

map.computeIfAbsent("1", key -> new Empl("dumnba")) 
like image 24
khelwood Avatar answered Oct 01 '22 17:10

khelwood