Java:HashMap 声称它有密钥,但不知何故没有
我有一个 HashMap 将 Context 类的对象映射到整数。在Context类中,我确实重写了java.lang.Object的public int hashCode()和public boolean equals(Object c)。但是,我在迭代它时遇到问题:
我想要(例如)获取分配给每个 Context 对象的 Integer 值,因此我迭代映射的键集。但它不起作用,因为映射说它没有指定的键:
for (Context to : map.keySet()) {
System.out.println("to-hash: " + to.hashCode());
System.out.println("first-hash: " + map.keySet().iterator().next().hashCode());
System.out.println("hashs equal: " + (to.hashCode()==map.keySet().iterator().next().hashCode()));
System.out.println("to equals first: " + to.equals(map.keySet().iterator().next()));
System.out.println("map has to? " + map.containsKey(to));
}
输出是
to-hash: 156349
first-hash: 156349
hashs equal: true
to equals first: true
map has to? false
根据我的理解,当给定一个键时,映射首先检查哈希码是否匹配,然后检查是否相等。这里的情况都是如此,“to”对象和键集中的第一个对象的哈希码匹配并且它们也相等。有趣的是,当我将 hashCode() 函数的返回值更改为常量(这是有效的,但出于性能原因不建议这样做)时,它起作用了。但我不明白为什么这会产生影响,因为 156349==156349 就像 7==7 一样。
我很困惑,我担心我错过了一些非常明显的东西,只是看不到它。如果是这样的话,我感到羞耻,但我仍然希望得到提示:-)
非常感谢!
I have a HashMap mapping objects of my Context class to Integers. In the Context class, I did override the public int hashCode() and public boolean equals(Object c) of java.lang.Object. However, I have problems iterating through it:
I want (e.g.) to get the Integer value assigned to each Context object, so I iterate through the key set of the map. But it doesn't work, because the map says it doesn't have the specified key:
for (Context to : map.keySet()) {
System.out.println("to-hash: " + to.hashCode());
System.out.println("first-hash: " + map.keySet().iterator().next().hashCode());
System.out.println("hashs equal: " + (to.hashCode()==map.keySet().iterator().next().hashCode()));
System.out.println("to equals first: " + to.equals(map.keySet().iterator().next()));
System.out.println("map has to? " + map.containsKey(to));
}
The output is
to-hash: 156349
first-hash: 156349
hashs equal: true
to equals first: true
map has to? false
From what I understand is that when given a key, the map first checks if the hash codes match, and then checks for equality. Both is the case here, the hash code of the 'to' object and the first object in the key set match and they are also equal. Interestingly, when I change the return value of the hashCode() function to a constant (which is valid, though not recommended for performance reasons), it works. But I don't see why this makes a difference, since 156349==156349 just like 7==7.
I'm quite confused, and I'm afraid that I'm missing something very obvious, and just can't see it. If that's the case, shame on me, but still, I would appreciate a hint :-)
Thanks a lot!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您的
Context
对象在某种程度上是可变的,会影响哈希码,并且您在将哈希码放入之后执行了更改哈希码的操作,则可能会发生这种情况地图。映射只会记录插入点的hashCode()
值,然后在您尝试查找特定键时使用该值来查找匹配项。如果您将哈希函数设置为常量,这将与其工作一致。基本上,您不应该在将哈希键放入映射后改变它们。
当然,这只是推测,但确实符合症状。
This could happen if your
Context
object is mutable in a way that affects the hash code, and if you've performed an operation which changes the hash code after putting it in the map. The map will only record the value ofhashCode()
at the point of insertion and then will use that to find matches when you try to look up a particular key.This would be consistent with it working if you make the hash function a constant. Basically, you shouldn't mutate hash keys after putting them in a map.
Of course, this is just conjecture, but it does fit the symptoms.