Saturday, May 11, 2013

Why can we use Enums as HashMap keys?

    Last time when I saw enum used as a HashMap key I decided to check why it works out of the box without custom implementations of 'hashCode' and 'equals' methods.
The HashMap keys must fulfill 'hashCode' and 'equals' contract in order to provide proper behaviour of HashMap. Every time the keyword enum appears in the code we deal with the implementations of java.lang.Enum class. Default implementation of 'hashCode' and 'equals' methods from java.lang.Enum:
public final int hashCode() {
        return super.hashCode();
}

public final boolean equals(Object other) {
        return this==other;
}
Enum delegates 'hashCode' implementation to 'java.lang.Object.hashCode' which is native method and returns different hash codes for different objects (addresses in memory). At first glance it looks like the negation of good practices for 'hashCode' and 'equals' implementations. However we have to burn one particular fact regarding enums in minds - enums instances are singletons. It is crucial property that allows for such implementations of mentioned methods. 'hashCode' will return the same value for the same objects (obligatory) and different values for different objects (boosts performance, because hash collisions are reduced). What is more, when it comes to enums we can use 'equals' as well as '==' to check equality.
Despite the fact that enums can be used as HashMap keys you may consider using EnumMap instead of HashMap with one caveat (I have observed it on JDK5 and JDK6 - JDK7u10 has resolved the problem).

No comments :

Post a Comment