Core JAVA

Difference between HashMap and IdentityHashMap

In this article, the Difference between HashMap and IdentityHashMap, we will discuss IdentityHashMap and difference between IdentityHashMap and HashMap. In previous articles, we have discussed very interesting topics such as How does HashMap work internally, and the difference between HashMap and TreeMap. Important points to be considered for choosing the right map implementation in the Java development. Also, discussed How does TreeMap work internally.

IdentityHashMap in Java

IdentityHashMap implements Map, Serializable and Clonable interfaces and extends AbstractMap class. We must avoid IdentityHashMap class for general purpose. While this class implements Map interface like other map implementation classes such as HashMap, LinkedHashMap, TreeMap, and HashTable. But it intentionally violates Map’s general contract which mandates the use of the equals method when comparing objects. This class is designed for use only in the rare cases wherein reference-equality semantics are required.

Constructors

  • IdentityHashMap(): Constructs a new, empty identity hash map with a default expected maximum size.
  • IdentityHashMap(int expectedMaxSize): Constructs a new, empty map with the specified expected maximum size.
  • IdentityHashMap(Map m): Constructs a new identity hash map containing the key-value mappings in the specified map.

Difference between HashMap and IdentityHashMap

IdentityHashMap in java is available since JDK 4, this class also implements the Map interface like HashMap and LinkedHashMap with a hash table. But the IdentityHashMap uses reference-equality in place of object-equality when comparing keys. Suppose in an IndentityHashMap, there are two keys key1 and key2, there two keys are considered equal if and only if (key1==key2).

But in HashMap implementation, there are two keys key1 and key2, these keys are considered equal if and only if (k1==null ? k2==null: k1.equals(k2)).) Let’s discuss this difference using an example as the following:

Create a Key class

Here I will create a new Key class, that will be used as the key for IdentityHashMap and HashMap.

package com.dineshonjava.algo.map;

/**
 * @author Dinesh.Rajput
 *
 */
public class Key{
	
	final int data = 112;
	private String key;
	
	public Key(String key) {
		super();
		this.key = key;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + data;
		result = prime * result + ((key == null) ? 0 : (key.charAt(0)+"").hashCode());
		System.out.println("hashCode for key: "+ key + " = " + result);
		System.out.println("Index "+ (result & 15));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		System.out.println("equals for key: ");
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Key other = (Key) obj;
		if (data != other.data)
			return false;
		if (key == null) {
			if (other.key != null)
				return false;
		} else if (!key.equals(other.key))
			return false;
		return true;
	}
	
}

In the above Key class, the hashCode() method is overridden so that it returns calculated hash value. The equals() method is overridden so that keys are equal if key and data are equal.

To understand the exact difference between IdentityHashMap and HashMap, we will simply try to write a small program to check what happens when we put some equal elements in HashMap and IdentityHashMap.

Putting value into HashMap

Let’s put same values into HashMap as the following:

package com.dineshonjava.algo.map;

import java.util.HashMap;
import java.util.Map;

/**
* @author Dinesh.Rajput
*
*/
public class HashMapTest {

/**
* @param args
*/
public static void main(String[] args) {
Map<Key, String> map = new HashMap<>();
Key key1 = new Key("Dinesh");
Key key2 = new Key("Dinesh");
Key key3 = new Key("Dinesh");
Key key4 = new Key("Dinesh");
map.put(key1 , "Dinesh");
map.put(key2 , "Dinesh");
map.put(key3 , "Dinesh");
map.put(key4 , "Dinesh");
System.out.println(map.size());
}

}

Note that all key objects are meaningfully equal and hence HashMap doesn’t allow duplicate keys, so it will print the size of Hashmap as 1.

Now let us try above program with IdentityHashMap.

Putting the values in IdentityHashMap

Let’s put same values into IdentityHashMap as the following:

package com.dineshonjava.algo.map;

import java.util.IdentityHashMap;
import java.util.Map;

/**
 * @author Dinesh.Rajput
 *
 */
public class IdentityHashMapTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Map<Key, String> map = new IdentityHashMap<>();
		Key key1 = new Key("Dinesh");
                Key key2 = new Key("Dinesh");
                Key key3 = new Key("Dinesh");
                Key key4 = new Key("Dinesh");
		map.put(key1 , "Dinesh");
		map.put(key2 , "Dinesh");
                map.put(key3 , "Dinesh");
		map.put(key4 , "Dinesh");
		System.out.println(map.size());
	}

}

This will print 4, because, for IdentityHashMap, all keys key1, key2, key3, and key4 are not meaningfully equal. If we refer to one object using 4 references like below,

Key key1 = new Key("Dinesh");
Key key2 = key1;
Key key3 = key1;
Key key4 = key1;

then they will qualify for equality, So the program below will output 1.

package com.dineshonjava.algo.map;

import java.util.IdentityHashMap;
import java.util.Map;

/**
 * @author Dinesh.Rajput
 *
 */
public class IdentityHashMapTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Map<Key, String> map = new IdentityHashMap<>();
                Key key1 = new Key("Dinesh");
                Key key2 = key1;
                Key key3 = key1;
                Key key4 = key1;
		map.put(key1 , "Dinesh");
		map.put(key2 , "Dinesh");
                map.put(key3 , "Dinesh");
		map.put(key4 , "Dinesh");
		System.out.println(map.size());
	}

}

While putting elements, now, all keys key1, key2, key3, and key4 are equal. Now size will be 1.

Hope this article will be able to explain the Difference between HashMap and IdentityHashMap.

Previous
Next
Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design Patterns using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

2 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

2 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

2 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

2 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

2 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

3 years ago