这似乎是一个简单的问题,但我现在已经尝试了几个小时(无需实现hashCode比较)来使containsKey工作.为简化起见,我将发布一个简单的代码示例,我遇到了以下问题:
public class myPair {
private int a;
private int b;
myPair(int x, int y) {
a=x;
b=y;
}
public boolean equals(Object pair) {
System.out.println("Ola");
return true;
}
int first() { return a; }
int second() { return b; }
public String toString() {
return "X: "+this.a + " Y:"+this.b;
}
}
public class Main {
public static void main(String args[]){
Map<myPair,String> myMap = new LinkedHashMap<myPair, String>();
myMap.put(new myPair(2, 2), "encontrou me");
if(myMap.containsKey(new myPair(2, 2))){
System.out.println(myMap.get(new myPair(2, 2)));
}
System.out.println(myMap.get(new myPair(2,2)));
}
}
Run Code Online (Sandbox Code Playgroud)
这输出:
null
Run Code Online (Sandbox Code Playgroud)
我已经实现了equals方法......为什么它不起作用?
aio*_*obe 11
因为必须覆盖hashCode
才能使用HashMap
(或LinkedHashMap
).这就是哈希映射的工作原理:它们首先计算哈希码,以便大致了解查找对象的位置.如果哈希码不等于目标对象哈希码,它只会在错误的位置查找对象!
这来自API文档Object.hashCode
:
- 如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果.
hashCode
大多数情况下,默认实现不会为两个不同的对象返回相同的哈希码.
基本上,你是通过覆盖equals
而不是违反API的合同hashCode
.