Java map.containsKey不起作用

out*_*der 4 java map

这似乎是一个简单的问题,但我现在已经尝试了几个小时(无需实现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.

  • 您可以尝试另一个地图实现,例如`TreeMap`(但是您的密钥需要具有可比性).但是,如果你重写`equals`,那么你违反了API的合同,如果你不*覆盖`hashCode`. (2认同)