Java map.containsKey不起作用

时间:2010-10-24 19:03:34

标签: 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)));
    }
}

输出:

null

我已经实现了equals方法......为什么它不起作用?

4 个答案:

答案 0 :(得分:11)

因为必须覆盖hashCode才能使用HashMap(或LinkedHashMap)。这就是哈希映射的工作原理:它们首先计算哈希码,以便大致了解查找对象的位置。如果哈希码不等于目标对象哈希码,它只会在错误的位置查找对象!

这来自Object.hashCode的API文档:

  
      
  • 如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果。
  •   

hashCode的默认实现大部分时间会为两个不同的对象返回相同的哈希码。

基本上,您通过覆盖equals而不是hashCode违反了API合同。

答案 1 :(得分:1)

您还需要按照aioobehvgotcodes的说明覆盖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。