2

我正在尝试使用以我的类 Cell 作为键的 HashMap。但是,在将一个项目放入 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

4 回答 4

4

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

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

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

于 2013-10-03T18:49:59.883 回答
1

考虑如何HashMap实现 a。放入时,首先计算对象hashCode(),以确定将对象放置在哪个桶中。当它试图检索一个对象时,它再次获取它的hashCode(),标识到目标桶,遍历桶中的链表,equals()对每个对象进行调用. 如果找到匹配项,则返回。

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

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

于 2013-10-03T18:49:18.823 回答
0

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

于 2013-10-03T18:49:28.043 回答
0

您可能忘记实现hashcode()for 函数Cell,为了在HashMap. 这是实现hashcode()功能的一种简单且通常准确的方法:

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

field1你班级中fieldN的字段在哪里。如果这些字段是原语(即int),只需取出toString().

于 2013-10-03T18:49:28.960 回答