A class like HashMap<T,U>
needs to have some means of identifying which item in the collection, if any, should be considered equivalent to a given item. There are two general means via which this can be accomplished:
Requiring that anything to be stored in a collection must include virtual methods to perform such comparison (and preferably provide a quick means (e.g. hashCode()
) of assigning partial equivalence classes).
Require that code which creates the collection must supply an object which can accept references to other objects and perform equivalence-related operations upon them.
It would have been possible to omit equals
and hashCode()
from Object
, and have types like HashMap
only be usable with key types that implement an equatable
interface that includes such members; code which wishes to use collections of references keyed by identity would have to use IdentityHashMap
instead. Such a design would not have been unreasonable, but the present design makes it possible for a general-purpose collection-of-collections type which uses HashMap
to be usable with things that are compared by value as well as by identity, rather than having to define a separate types for collection-of-HashMap and collection-of-IdentityHashMap.
An alternative design might have been to have a GeneralHashMap
type whose constructor requires specifying a comparison function, and have IdentityHashMap
and HashMap
both derive from that; the latter would constrain its type to equatable
and have its identity functions chain to those of the objects contained therein. There would probably have been nothing particularly wrong with that design, but that's not how things were done.
In any case, there needs to be some standard means by which collections can identify items that should be considered equivalent; using virtual equals(Object)
and getHashCode()
is a way of doing that.