Open In App

Internal Working of HashMap in Java

In this article, we will see how the hashmap get and put method works internally. What operations are performed? How the hashing is done. How the value is fetched by key. How the key-value pair is stored.
In the previous article, HashMap contains an array of Node and Node can represent a class having the following objects : 

  1. int hash
  2. K key
  3. V value
  4. Node next

Now we will see how this works. First, we will see the hashing process. 



Hashing

Hashing is a process of converting an object into integer form by using the method hashCode(). It’s necessary to write the hashCode() method properly for better performance of HashMap. Here I am taking the key of my class so that I can override the hashCode() method to show different scenarios. My Key class is 



//custom Key class to override hashCode()
// and equals() method
class Key
{
String key;
Key(String key)
{
this.key = key;
}

@Override
public int hashCode()
{
return (int)key.charAt(0);
}

@Override
public boolean equals(Object obj)
{
return key.equals((String)obj);
}
}

Here override hashCode() method returns the first character’s ASCII value as hash code. So whenever the first character of the key is same, the hash code will be the same. You should not approach these criteria in your program. It is just for demo purposes. As HashMap also allows a null key, so hash code of null will always be 0.

hashCode() method: hashCode() method is used to get the hash code of an object. hashCode() method of the object class returns the memory reference of an object in integer form. Definition of hashCode() method is public native hashCode(). It indicates the implementation of hashCode() is native because there is not any direct method in java to fetch the reference of the object. It is possible to provide your implementation of hashCode(). 
In HashMap, hashCode() is used to calculate the bucket and therefore calculate the index. 

equals() method: This method is used to check whether 2 objects are equal or not. This method is provided by the Object class. You can override this in your class to provide your implementation. 
HashMap uses equals() to compare the key to whether they are equal or not. If the equals() method return true, they are equal otherwise not equal. 

Buckets: A bucket is an element of the HashMap array. It is used to store nodes. Two or more nodes can have the same bucket. In that case, a link list structure is used to connect the nodes. Buckets are different in capacity. A relation between bucket and capacity is as follows: 

capacity = number of buckets * load factor

A single bucket can have more than one node, it depends on the hashCode() method. The better your hashCode() method is, the better your buckets will be utilized. 

Index Calculation in Hashmap

Generated hash code may be in the range of integer and if we create arrays for such a range, then it will easily cause outOfMemoryException. So we generate an index to minimize the size of the array. The following operation is performed to calculate the index. 

index = hashCode(key) & (n-1).

where n is the number of buckets or the size of the array. In our example, I will consider n as the default size which is 16. 

Why the above method is used to calculate the index

Using a bitwise AND operator is similar to doing bit masking wherein only the lower bits of the hash integer is considered which in turn provides a very efficient method of calculating the modulus based on the length of the hashmap.

HashMap map = new HashMap();

map.put(new Key("vishal"), 20);
{
int hash = 118

// {"vishal"} is not a string but
// an object of class Key
Key key = {"vishal"}

Integer value = 20
Node next = null
}
  1. Place this object at index 6, if no other object is presented there.
map.put(new Key("sachin"), 30);
{
int hash = 115
Key key = {"sachin"}
Integer value = 30
Node next = null
}
map.put(new Key("vaibhav"), 40);
 {
int hash = 118
Key key = {"vaibhav"}
Integer value = 40
Node next = null
}
  1. Place this object at index 6 if no other object is presented there.
  2. In this case, a node object is found at index 6 – this is a case of collision.
  3. In that case, check via the hashCode() and equals() method if both the keys are the same.
  4. If keys are the same, replace the value with the current value.
  5. Otherwise, connect this node object to the previous node object via linked list and both are stored at index 6. 
    Now HashMap becomes :

 

Using the get method()

Now let’s try some get methods to get a value. get(K key) method is used to get a value by its key. If you don’t know the key then it is not possible to fetch a value. 

map.get(new Key("sachin"));
map.get(new Key("vaibhav"));

Article Tags :