I was messing around with some hashCode + equals + Map stuff and found something ... weird.
The snippet is as follows:
class Obj {
String n;
Obj(String n) {this.n = n;}
public int hashCode() {return 0;}
public boolean equals(Object o) {return false;} // no instance of this class
// equals any other instance
}
Then I did something like this:
java.util.Map<Obj,String> map = new java.util.HashMap<Obj,String>();
Obj o1 = new Obj("1");
Obj o11 = new Obj("1");
Obj o2 = new Obj("2");
map.put(o1,"val 1");
map.put(o11,"val 2");
map.put(o2,"val 3");
p("size = " + map.size()); // obviously 3
p(map.get(new Obj("1"))); // obviously null
p(map.get(o1)); // ...
The last line is the weird part. The last line returns val 1
. How come? The equals
method always returns false
. Is this because the ==
operator is used before equals
is called?
Thanks for any insight.
In HashMap.java, the get
method is:
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
The line if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
does indeed compare the keys using ==
before calling equals
. That is why your attempt to eliminate equality fails.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With