Java HashMap包含的值始终为false

Java HashMap包含的值始终为false,java,hashmap,contains,Java,Hashmap,Contains,我有一个有趣的情况,我将坐标存储到HashMap中 现在,奇怪的是,我有一段代码,应该加以保护,没有坐标应该被使用两次。但如果我调试此代码: if (mapForLevel.containsKey(coord)) { throw new IllegalStateException("This coordinate is already used!"); } else { ...do stuff... } 。。。containsKey总是返回false,尽管我在地图中存储了一个h

我有一个有趣的情况,我将
坐标
存储到
HashMap

现在,奇怪的是,我有一段代码,应该加以保护,没有坐标应该被使用两次。但如果我调试此代码:

if (mapForLevel.containsKey(coord)) {
    throw new IllegalStateException("This coordinate is already used!");
} else {
    ...do stuff...
}
。。。
containsKey
总是返回
false
,尽管我在地图中存储了一个hashcode为9731的坐标,并且当前坐标也有hashcode 9731

之后,
mapForLevel.entrySet()
如下所示:

(java.util.HashMap$EntrySet) [(270,90)=gui.GUIGameField@29e357, (270,90)=gui.GUIGameField@ca470]
我可能做错了什么?我没有主意了。谢谢你的帮助

public class Coordinate {
    int xCoord;
    int yCoord;

    public Coordinate(int x, int y) {
        ...store params in attributes...
    }

    ...getters & setters...

    @Override
    public int hashCode() {
        int hash = 1;
        hash = hash * 41 + this.xCoord;
        hash = hash * 31 + this.yCoord;
        return hash;
    }
}

除了
hashCode
之外,还应该重写
equals
,以使其正常工作


编辑:我错误地声明您应该在
equals
中使用
hashCode
——这是不正确的。虽然
hashCode
必须为两个相等的对象返回相同的结果,但它仍然可以为不同的对象返回相同的结果

Coordinate
类中定义
hashCode
方法确保它为唯一对象返回唯一代码,为相同对象返回相同代码。

似乎您忘记为坐标类实现
equals()
方法。这是合同要求的。Hah使用equals比较具有相同哈希代码的两个条目。在您的情况下,调用对象.equals()对于两个不同的对象总是不同的,因为它基于对内存中对象的引用。

您需要在hashCode中同时实现equals的原因是因为哈希表的工作方式

哈希表将整数值(键的哈希)与该值相关联。 将其视为一个值对象数组。在该表中插入时,值存储在位置key.hashCode()处

这允许您“直接”查找表中的任何对象。您只需计算该对象的哈希代码,就可以知道它在表中的位置。将其视为与树相反的情况,在树中您需要导航树以查找对象)

但是,这种方法存在一个问题:可能有多个对象具有相同的哈希代码。 这将导致您错误地将两个(或多个)键与相同的值关联。这叫做碰撞

有一种简单的方法可以解决这个问题:不必将每个hashcode映射到一个值,而可以将其映射到一个键值对列表

现在,每当您在哈希映射中查找对象时,在计算哈希之后,您需要遍历该列表(与该哈希代码相关的“值”列表)并找到正确的值

这就是为什么总是需要在哈希映射的键上实现等于


注意:哈希表实际上比这个复杂一点,但想法是一样的。您可以阅读有关冲突解决的更多信息。

您是否同时重写坐标类中的
equals()
hashCode()
方法?
equals
不应该使用
hashCode
是的,同样感谢您,我认为hashCode在这里起作用。好的,我已经这样做了,就像代码片段显示的那样,但既然现在已经解决了,还是要谢谢你的建议。