Core Java

Java – HashMap in-detail explanation

HashMap works based on hashing algorithm, As per Java doc HashMap has below four constructors,

ConstructorDescription
HashMap​()Constructs an empty
HashMap with the default initial capacity (16) and the default load factor (0.75).
HashMap​(int initialCapacity)Constructs an empty
HashMap with the specified initial capacity and the default load factor (0.75).
HashMap​(int initialCapacity,
float loadFactor)
Constructs an empty
HashMap with the specified initial capacity and load factor.
HashMap​(Map<? extends K,? extends V> m)Constructs a new
HashMap with the same mappings as the specified
Map.

Let’s write simple java program, to examine how Map works internally

  1. Create a simple Map and add one key and value to it
public static void main(String[] args) {

Map<Integer, String> map = new HashMap<>();

map.put(1, "Java");

}

We just created Simple Map, which takes key as Integer and Value as String, and added “1” as Key and “Java” as value. By using eclipse debug feature, lets see what’s inside the map

It created 16 blocks(0-15) and inserted 1st block with key as Integer “1” and Value as String “Java”. Please check the red box, rest all boxes initialized with  null.

2. Add second key and value to the same map

public static void main(String[] args) {

Map<Integer, String> map = new HashMap<>();

map.put(1, "Java");

map.put(2, "Angular");

}

lets see the map in eclipse debug again

Now the map contains two keys (1,2) and two values (“Java”, “Angular”) as expected, but the keys are added exactly at 1st block and 2nd block respectively, why?

because as we know Map works based on hashing algorithm, whenever we insert key to map, it calls the Object#hashcode() method, based on the value of hashCode(), it will insert the key into that block.

In above case, Integer class overrides the hashCode with its primitive int value, thats why (1,java) got stored in 1st block and (2,Angular) got store in 2nd block.

3. Lets do the same experiment with our own Class

Create a simple Employee class like below

private static class Employee{
int id;
String name;

Employee(int id, String name){
this.id = id;
this.name = name;
}
}

Use this class as Key to the map and examine the same way

public static void main(String[] args) {
Map<Employee, String> map = new HashMap<>(10);
map.put(new Employee(1, "Ramesh"), "Java");
map.put(new Employee(2, "Sathish"), "Angular");
}

We have added two keys as Employee objects and Values as just strings, lets see in which block the keys got stored this time

This time, it stored in 8th block and 14th block(why? simple answer because of hashCode of Employee objects), to confirm this, lets override hashCode() of Employee to constant value and check the map. If our analysis correct it has to store all the key’s in the same block.

Update Employee class accordingly

private static class Employee{
int id;
String name;
Employee(int id, String name){
this.id = id;
this.name = name;
}
@Override
public int hashCode() {
return 10;
}
}

We dont need to change anything to our map, lets see now where the keys got stored

Yes, only 10th block got filled with two objects, why? because both employee objects returned the same hashCode (i.e 10). But how does Map recognized those two objects are not duplicate? As we know internally Map#Key is an entrySet(java.util.Set) it called equals method to verify whether the key is duplicate or not.

While retrieving the value from Map also, first it will check the hashCode of the given key and based on that it will go to that block, after finding the block it will call equals() to get the exact value.

So overriding the hashCode() to constant is not at all recommendable. and when we override the hashCode() we should not forget to override the equals() method as well(i.e hashCode()/equals() contract).

Published on Java Code Geeks with permission by Ramesh Kotha, partner at our JCG program. See the original article here: Java – HashMap in-detail explanation

Opinions expressed by Java Code Geeks contributors are their own.

Ramesh Kotha

Ramesh is a certified Java professional working in financial domain, He is an application developer and has hands on practice with Java and related technologies. He is passionate about Spring and other open source technologies.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button