Pages

Difference between IdentityHashMap, WeakHashMap and EnumMap in Java

Apart from popular implementation like HashMap and LinkedHashMap, java.util.Map also has some specialized implementation classes e.g. IdentifyHashMapwhich uses == instead of equals() method for comparing keys, WeakHashMap which uses WeakReference to wrap the key object and a key/value mapping is removed when the key is no longer referenced from elsewhere, and EnumMap where keys are Enum constants. Many Java developer doesn't know about these special Map implementation classes and failed to take advantage of improved performance and feature offered by them. Their knowledge is also important from core Java interview perspective because Java interviewer put a huge focus on JDK API, particularly Java Collection framework and Java Concurrency framework which includes concurrent collections classes.
Now that you know the basic difference between IdentityHashMap, EnumMap, and WeakHashMap, let's learn little more about their unique features to understand them better. It's not necessary that you have to use it but if you know how they work and when they are used will help you to understand existing code and help in troubleshooting and debugging.

IdentityHashMap vs WeakHashMap vs EnumMap in Java

As I told each of these are special Map implementation classes and has unique uses. In order to learn when to use them, you must learn the unique feature they offer and their difference with general purposes Map implementations like HashMap, LinkedHashMap, and Hashtable.

1) The fundamental difference between IdentityHashMap and other Map implementations e.g. HashMap, Hashtable, WeakHashMap or EnumMap it uses equality operator (==) to search and get the value back. If you know how to get method of Map works the know that other Map implementation, which uses equals() method of the key object for that purpose.

Since == operator only return true if the reference variables point to the same object, it's not possible to get the value with a different object even if it appear equal in all field. You must hold the reference of the key object outside the IdentityHashMap to get the value back.

Another consequence of using == operator instead of equals() method is that there would be less collision compared to other Map implementations e.g. HsahMap. See Java Performance The Definitive Guide By Scott Oaks to learn more about the performance impact of collisions in HashMap.

2) The fundamental difference between WeakHashMap and other Map classes like HashMap, IdentityHashMap and EnumMap is that its keys are WeakReferences, which means both key and value becomes eligible to garbage collection if a key is no longer referenced from elsewhere in the program.

This property makes WeakHashMap a good candidate for using as Cache in memory constraint environment because Map itself will take care of removing unused Mapping. On the other hand, this can cause unusual behavior if later removed key is passed from the different part of a program. See Core Java Volume 1 - Fundamentals by Cay S. Horstmann to learn more about WeakHashMap and its practical usage.

3) The third one, EnumMap is a special Map implementations for Enum keys, this is also the fundamental difference between EnumMap and another general purpose Map class e.g. HashMap or Hashtable. Unlike others EnumMap only allows Enum constants to be used as keys. If you try to store keys other than Enum than compiler will throw an error.

It's a special implementation for Enums hence it takes advantage of key universe i.e. number of Enum constants and creates the backup array with the same size as of key universe. See Java Performance Companion by Charlie Hunt to understand performance benefit of EnumMap in Java application.

When to use EnumMap, WeakHashMap, and IdentityHashMap in Java

Now that you know their special feature, it's easy to decide when to use them. Use IdentityHashMap if use needs strict equality check by using == operator. It's not a general purpose Map because it doesn't use equals() method for comparing keys, hence also breaks Map interface's contract.

Use EnumMap if you are using Enum constants as keys. It will probably take less memory and give better performance than HashMap or any other general purpose Map. It also has a good chance to be upgraded or replaced by another more performant implementation.

You can use WeakHashMap if you are storing mapping in a memory constraint environment and you are ok with keys disappearing suddenly. Since WeakHashMap uses keys with WeakReference they become eligible for GC once the external reference to the key is removed. It's often used as Cache in Java. You can further read Big Java: Early Objects 5th Edition to learn more about these specialized classes of Java Collection framework.

Anyway, here is a nice summary of their performance for common operations like storing mapping, retrieving mapping, and searching keys and values:

That's all about the difference between IdentityHashMap, WeakHashMap, EnumMap and other general purpose Map implementations in Java. Just remember their unique feature and when to use them. Most likely you will not use them on a daily basis but when situation arise you will appreciate them for their unique offering.