How HashMap works in java

Most common interview questions are <code>How HashMap works in java</code>, “How get and put method of HashMap work internally”. Here I am trying to explain internal functionality with an easy example.
HashMap is one of the most used Collections in java.Rather than going through theory, we will start with example first, so that you will get better understanding and then we will see how get() and put() function work in java.

Let’s take a very simple example. I have a
Country class, we are going to use Country class object as key and its
capitalname (string) as value. Below example will help you to understand, how these key value pair will be stored in hashmap.

1.
Country.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

packageorg.arpit.java2blog;

publicclassCountry{

Stringname;

longpopulation;

publicCountry(Stringname,longpopulation){

super();

this.name=name;

this.population=population;

}

publicStringgetName(){

returnname;

}

publicvoidsetName(Stringname){

this.name=name;

}

publiclonggetPopulation(){

returnpopulation;

}

publicvoidsetPopulation(longpopulation){

this.population=population;

}

// If length of name in country object is even then return 31(any random number) and if odd then return 95(any random number).

// This is not a good practice to generate hashcode as below method but I am doing so to give better and easy understanding of hashmap.

Iterator countryCapitalIter=countryCapitalMap.keySet().iterator();//put debug point at this line

while(countryCapitalIter.hasNext())

{

Country countryObj=countryCapitalIter.next();

Stringcapital=countryCapitalMap.get(countryObj);

System.out.println(countryObj.getName()+"----"+capital);

}

}

}

Now put debug point at line 24 and right click on project->debug as-> java application. Program will stop execution at line 24 then right click on
countryCapitalMap then select watch.You will be able to see structure as below.

Now From above diagram, you can observe the following points

There is an
Entry[] array called table which has size 16.

This table stores Entry class’s object. HashMap class has an inner class called
Entry . This Entry have key value as an instance variable. Let’s see structure of entry class Entry Structure.

1

2

3

4

5

6

7

8

9

10

staticclassEntry implementsMap.Entry

{

finalKkey;

Vvalue;

Entry next;

finalinthash;

...//More code goes here

}

Whenever we try to put any key value pair in hashmap, Entry class object is instantiated for key value and that object will be stored in above mentioned
Entry[] (table). Now you must be wondering, where will above created Entry object get stored(exact position in table). The answer is, hash code is calculated for a key by calling Hascode() method. This hashcode is used to calculate index for above Entry[] table.

Now, If you see at array index 10 in above diagram, It has an Entry object named
HashMap$Entry .

We have put 4 key-values in Hashmap but it seems to have only 2!!!! This is because if two objects have same hashcode, they will be stored at same index. Now the question arises how? It stores objects in the form of
LinkedList (logically).

So how hashcode of above country key-value pairs are calculated.

1

2

3

4

5

6

Hashcode forJapan=95asits length isodd.

Hashcode forIndia=95asits length isodd

HashCode forRussia=31asits length iseven.

HashCode forFrance=31asits length iseven.

Below diagram will explain LinkedList concept clearly.

So now if you have good understanding of
Hashmap structure,Lets go through put and get method.

Put

Let’s see the implementation of put method:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

/**

* Associates the specified value with the specified key in this map. If the

* map previously contained a mapping for the key, the old value is

* replaced.

*

* @param key

* key with which the specified value is to be associated

* @param value

* value to be associated with the specified key

* @return the previous value associated with <tt>key</tt>, or <tt>null</tt>

* if there was no mapping for <tt>key</tt>. (A <tt>null</tt> return

* can also indicate that the map previously associated

* <tt>null</tt> with <tt>key</tt>.)

*/

publicVput(Kkey,Vvalue){

if(key==null)

returnputForNullKey(value);

inthash=hash(key.hashCode());

inti=indexFor(hash,table.length);

for(Entrye=table[i];e!=null;e=e.next){

Objectk;

if(e.hash==hash&&((k=e.key)==key||key.equals(k))){

VoldValue=e.value;

e.value=value;

e.recordAccess(this);

returnoldValue;

}

}

modCount++;

addEntry(hash,key,value,i);

returnnull;

}

now lets understand above code step by step

Key object is checked for null. If key is null then it will be stored at
table[0] because hashcode for null is always 0.

Key object’s hashcode() method is called and hash code is calculated. This hashcode is used to find index of array for storing Entry object. It may happen sometimes that, this hashcode function is poorly written so JDK designer has put another function called hash() which takes above-calculated hash value as argument. If you want to learn more about hash() function, you can refer hash and indexFor method in hashmap.

indexFor(hash,table.length) is used to calculate exact index in table array for storing the Entry object.

As we have seen in our example, if two key objects have same hashcode(which is known as collision) then it will be stored in form of linkedlist.So here, we will iterate through our linkedlist.

If there is no element present at that index which we have just calculated then it will directly put our Entry object at that index.

If There is element present at that index then it will iterate until it gets
Entry->next as null.

What if we are putting same key again, logically it should replace old value. Yes, it will do that. While iterating it will check key equality by calling
equals() method(key.equals(k)), if this method returns true then it replaces value object with current Entry’s value object.

If it did not find the duplicate key, then current
Entry object will become first node in linkedlist and current Entry -> next will become an existing first node on that index.

Get

Lets see implementation of get now:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

/**

* Returns the value to which the specified key is mapped, or {@code null}

* if this map contains no mapping for the key.

*

*

* More formally, if this map contains a mapping from a key {@code k} to a

indexFor(hash,table.length) is used to calculate exact index in table array using generated hashcode for getting the Entry object.

After getting index in table array, it will iterate through linkedlist and check for key equality by calling equals() method and if it returns true then it returns the value of Entry object else returns null.