HashMap不会根据键返回值

时间:2013-10-03 18:46:21

标签: java hashmap

我正在尝试将HashMap与我的类Cell作为关键。但是,在将项目放入HashMap之后,在项目上调用contains将返回false。

public static void main(String args[]) {
        HashMap<Cell, String> map = new HashMap<Cell, String>();
        map.put(new Cell(0,0), "Bob");
        System.out.println(map.containsKey(new Cell(0,0)));
        System.out.println(new Cell(0,0).equals(new Cell(0,0)));
}

这打印出false和true,它应该打印true和true,因为根据Map docs containsKey使用.equals()。我做错了什么?

4 个答案:

答案 0 :(得分:4)

这很可能是因为您没有实施equals()hashCode()。在Java中,经验法则是如果实现一个,则必须实现另一个。在您的情况下,它是强制性的,因为HashMap使用它们。

您创建了两个具有两个单独地址的独立对象。如果没有这些方法,JVM无法知道对象是“相同的”。

请参阅http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()

答案 1 :(得分:1)

考虑如何实施HashMap。放置时,它首先计算对象hashCode()以确定放置对象的桶。当它尝试检索对象时,它再次获取其hashCode(),标识到目标桶,通过存储桶中的链接列表,针对每个对象调用equals()。如果找到匹配则返回。

换句话说,当您使用HashMap时,您需要拥有equals()hashCode()的正确匹配实现。

hashCode()继承的默认Object方法无法正确返回相同的hashCode(),除非对象引用相同。在你的情况下,他们不是。

答案 2 :(得分:0)

多次调用new Cell(0,0)会产生具有不同哈希码的不同对象。您应该为Cell类实现hashCode。

答案 3 :(得分:0)

您可能忘记为hashcode()实施Cell函数,这也是在HashMap中使用用户定义的类所必需的。以下是实现hashcode()函数的简单且通常准确的方法:

int hashcode(){
    return (field1.toString()+field2.toString()+...+fieldN.toString()).hashcode();
}

field1fieldN是您班级中的字段。如果字段是主要字段(即int),则只需取出toString()