Java:HashMap声称它有密钥,但不知何故没有

buf*_*run 0 java iterator hashmap set keyset

我有一个HashMap将Context类的对象映射到Integers.在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));
}
Run Code Online (Sandbox Code Playgroud)

输出是

to-hash: 156349
first-hash: 156349
hashs equal: true
to equals first: true
map has to? false
Run Code Online (Sandbox Code Playgroud)

据我所知,当给定一个键时,映射首先检查哈希码是否匹配,然后检查是否相等.两者都是这里的情况,'to'对象的哈希码和键集中的第一个对象匹配,它们也是相等的.有趣的是,当我将hashCode()函数的返回值更改为常量(这是有效的,但出于性能原因而不推荐)时,它可以正常工作.但我不明白为什么这会产生影响,因为156349 == 156349就像7 == 7.

我很困惑,我担心我会遗漏一些非常明显的东西,而且看不到它.如果是这样的话,对我感到羞耻,但仍然,我会感激一个提示:-)

非常感谢!

Jon*_*eet 9

如果您的Context对象以影响哈希代码的方式可变,并且您已经执行了将哈希代码放入地图更改哈希代码的操作,则可能会发生这种情况.地图将仅记录hashCode() 插入点的值,然后在您尝试查找特定键时使用该值来查找匹配项.

如果将哈希函数设为常量,这将与它一致.基本上,在将哈希键放入地图后,不应该改变哈希键.

当然,这只是猜想,但它确实符合症状.