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在这里起作用。好的,我已经这样做了,就像代码片段显示的那样,但既然现在已经解决了,还是要谢谢你的建议。