Use cases for IdentityHashMap

Java

Java Problem Overview


Could anyone please tell what are the important use cases of IdentityHashMap?

Java Solutions


Solution 1 - Java

Whenever you want your keys not to be compared by equals but by == you would use an IdentityHashMap. This can be very useful if you're doing a lot of reference-handling but it's limited to very special cases only.

Solution 2 - Java

The documentations says:

> A typical use of this class is > topology-preserving object graph > transformations, such as serialization > or deep-copying. To perform such a > transformation, a program must > maintain a "node table" that keeps > track of all the object references > that have already been processed. The > node table must not equate distinct > objects even if they happen to be > equal. Another typical use of this > class is to maintain proxy objects. > For example, a debugging facility > might wish to maintain a proxy object > for each object in the program being > debugged.

Solution 3 - Java

One case where you can use IdentityHashMap is if your keys are Class objects. This is about 33% faster than HashMap for gets! It probably uses less memory too.

Solution 4 - Java

You can also use the IdentityHashMap as a general purpose map if you can make sure the objects you use as keys will be equal if and only if their references are equal.

To what gain? Obviously it will be faster and will use less memory than using implementations like HashMap or TreeMap.


Actually, there are quite a lot of cases when this stands. For example:

  • Enums. Although for enums there is even a better alternative: EnumMap
  • Class objects. They are also comparable by reference.
  • Interned Strings. Either by specifying them as literals or calling String.intern() on them.
  • Cached instances. Some classes provide caching of their instances. For example quoting from the javadoc of Integer.valueOf(int): > This method will always cache values in the range -128 to 127, inclusive...
  • Certain libraries/frameworks will manage exactly one instance of ceratin types, for example Spring beans.
  • Singleton types. If you use istances of types that are built with the Singleton pattern, you can also be sure that (at the most) one instance exists from them and therefore reference equality test will qualify for equality test.
  • Any other type where you explicitly take care of using only the same references for accessing values that were used to putting values into the map.

To demonstrate the last point:

Map<Object, String> m = new IdentityHashMap<>();

// Any keys, we keep their references
Object[] keys = { "strkey", new Object(), new Integer(1234567) };

for (int i = 0; i < keys.length; i++)
    m.put(keys[i], "Key #" + i);

// We query values from map by the same references:
for (Object key : keys)
    System.out.println(key + ": " + m.get(key));

Output will be, as expected (because we used the same Object references to query values from the map):

strkey: Key #0
java.lang.Object@1c29bfd: Key #1
1234567: Key #2

Solution 5 - Java

HashMap creates Entry objects every time you add an object, which can put a lot of stress on the GC when you've got lots of objects. In a HashMap with 1,000 objects or more, you'll end up using a good portion of your CPU just having the GC clean up entries (in situations like pathfinding or other one-shot collections that are created and then cleaned up). IdentityHashMap doesn't have this problem, so will end up being significantly faster.

See a benchmark here: http://www.javagaming.org/index.php/topic,21395.0/topicseen.html

Solution 6 - Java

This is a practical experience from me:

IdentityHashMap leaves a much smaller memory footprint compared to HashMap for large cardinalities.

Solution 7 - Java

One important case is where you are dealing with reference types (as opposed to values) and you really want the correct result. Malicious objects can have overridden hashCode and equals methods getting up to all sorts of mischief. Unfortunately, it's not used as often as it should be. If the interface types you are dealing with don't override hashCode and equals, you should typically go for IdentityHashMap.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIsabel JinsonView Question on Stackoverflow
Solution 1 - JavaB.E.View Answer on Stackoverflow
Solution 2 - JavasrisView Answer on Stackoverflow
Solution 3 - JavaNateSView Answer on Stackoverflow
Solution 4 - JavaiczaView Answer on Stackoverflow
Solution 5 - JavaEliView Answer on Stackoverflow
Solution 6 - JavarfangView Answer on Stackoverflow
Solution 7 - JavaTom Hawtin - tacklineView Answer on Stackoverflow