There are some cases that the key objects used in map do not override hashCode() and equals() from Object, for examples, use a socket Connection or java.lang.Class as keys.
- Is there any potential defect to use these objects as keys in a HashMap?
- Should I use IdentityHashMap in these cases?
If
equals()andhashCode()are not overridden on key objects, HashMap and IdentityHashMap should have the same semantics. The default equals() implementation uses reference semantics, and the defaulthashCode()is the system identity hash code of the object.This is only harmful in cases where different instances of an object can be considered logically equal. For example, you would not want to use IdentityHashMap if your keys were:
and
Since these are technically different instances of the Integer class. (You should really be using
Integer.valueOf(1), but that’s getting off-topic.)Classas keys should be okay, except in very special circumstances (for example, the hibernate ORM library generates subclasses of your classes at runtime in order to implement a proxy.) As a developer I would be skeptical of code which storesConnectionobjects in a Map as keys (maybe you should be using a connection pool, if you are managing database connections?). Whether or not they will work depends on the implementation (since Connection is just an interface).Also, it’s important to note that HashMap expects the
equals()andhashCode()determination to remain constant. In particular, if you implement some customhashCode()which uses mutable fields on the key object, changing a key field may make the key get ‘lost’ in the wrong hashtable bucket of the HashMap. In these cases, you may be able to use IdentityHashMap (depending on the object and your particular use case), or you might just need a differentequals()/hashCode()implementation.