两个不同的对象可以具有相同的哈希代码并且相等。如何通过引用获取实际对象?
例如:-
class Dog {
public String name;
public Dog(String n){
this.name = n;
}
public boolean equals(Object o){
if((o instanceof Dog) && ((Dog)o).name.length() == this.name.length()){
return true;
}else{
return false;
}
}
public int hashCode(){
return name.length();
}
@Override
public String toString(){
return name;
}
}
public class MapTest {
public static void main(String ar[]){
Map<Object, Object> m = new HashMap<Object, Object>();
Dog d1 = new Dog("clover");
Dog d2 = new Dog("abcdef");
m.put(d1, new Dog("aiko1"))
m.put(d2, new Dog("aiko"));
System.out.println(m.get(d1));
System.out.println(m.get(d2));
}
}
输出:-
爱子
爱子
然而,d1 的值是 aiko1,但是当我们获取时,打印的值是 aiko。我们如何获取实际的 d1 值?
让我解释一下在这种情况下HashMap
是如何工作的。
- 首先,您已经覆盖了
hashCode()
方法 -
HashMap
先看看。 - 您正在使用
name
字段length
作为哈希代码。
" - Clover"和"abcdef"都将返回相同的哈希代码,即6。
- 现在它是一种碰撞状态,因此
HashMap
将下降到equals
方法进一步检查它,再次被您覆盖。 - 但是在
equals
这里,你又在做同样的事情。在这里,您也在比较name
字段的长度。 - 在这种情况下,两个键是相同的,因此它将覆盖最后一个值。
您可以验证它,但在方法结束时调用m.size()
main
。
但我建议使用 String
作为名称字段的键。
Map<String, Object> m = new HashMap<String, Object>();
在这种情况下,您无需覆盖hashCode
,也不需要覆盖equals
。
import java.util.HashMap;
import java.util.Map;
class Dog {
public String name;
public Dog(String n) {
this.name = n;
}
@Override
public String toString() {
return name;
}
}
public class MapTest {
public static void main(String ar[]) {
Map<String, Object> m = new HashMap<String, Object>();
Dog d1 = new Dog("clover");
Dog d2 = new Dog("abcdef");
m.put(d1.name, new Dog("aiko1"));
m.put(d2.name, new Dog("aiko"));
System.out.println(m.get(d1.name));
System.out.println(m.get(d2.name));
}
}
由于您的两个键(d1
和 d2
)是相等的(根据您对 eqauls(Object)
的实现),映射中没有两个元素 - 只有一个。对 put
的第二次调用将覆盖以前的值。