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 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.
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:
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.
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.
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.
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…