So, it's regardless whether k
is "equivalent" to key
, k
must be ==
to key
.
No, that is incorrect, as @KevinWallis already observed. HashMap
uses hashCode()
to identify the correct hash bucket, and equals()
, not ==
, to compare keys that fall into the same bucket. Types that have a meaningful sense in which distinct instances are equivalent are supposed to describe that via their equals()
methods, and standard library types such as String
and Integer
in fact do so. When the keys are of such a type, you do not have to use the same object to retrieve a value from a HashMap
that you did to store it.
On the other hand, types that do not have a meaningful sense in which distinct instances are equivalent should not, and generally do not, override equals()
(or hashCode()
). The implementation inherited from Object
yields the same result as the ==
operator, which makes it possible and sensible to use such objects as HashMap
keys or to store them in HashSet
s, at least under some circumstances.
Is it possible to change this behaviour in order to use only hashCode() equivalence?
It is not possible to change the behavior of HashMap
in this regard. If you were able to do so then the resulting map would not correctly fulfill the Map
contract. You can, however, implement your own map-like class that behaves as you describe, or you can create a wrapper class to use as a substitute key type.
Example key class:
class HashEquivalenceKey<T> {
private final T object;
public HashEquivalenceKey(T object) {
this.object = object;
}
public int hashCode() {
return ((o == null) ? 0 : object.hashCode());
}
public boolean equals(Object o) {
return ((o != null) && (this.hashCode() == o.hashCode()));
}
}