这似乎是一个简单的问题,但我现在已经尝试了几个小时(无需实现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)));
}
}
输出:
null
我已经实现了equals方法......为什么它不起作用?
答案 0 :(得分:11)
因为必须覆盖hashCode
才能使用HashMap
(或LinkedHashMap
)。这就是哈希映射的工作原理:它们首先计算哈希码,以便大致了解查找对象的位置。如果哈希码不等于目标对象哈希码,它只会在错误的位置查找对象!
这来自Object.hashCode
的API文档:
- 如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果。
hashCode
的默认实现大部分时间不会为两个不同的对象返回相同的哈希码。
基本上,您通过覆盖equals
而不是hashCode
违反了API合同。
答案 1 :(得分:1)
您还需要按照aioobe和hvgotcodes的说明覆盖hashCode
方法。
由于equals
始终返回true
,因此hashCode
方法必须始终返回相同的值:
@Override
public int hashCode() {
return 123; // qualquer número (any other number)
}
但我怀疑使用equals
方法的对象始终返回true
非常有用。至少不是地图的关键:由于没有不同的关键字,因此无法在地图中拥有多个键值对。 (可能对测试有用)
答案 2 :(得分:0)
你需要一个hashCode方法,你的equals方法总是返回true,这是不正确的。
答案 3 :(得分:-4)
你可以从Khalid Mughal和Rolf W Rasmussen的优秀着作中学习这些概念。它叫做SCJP。