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

标签 java iterator set hashmap keyset

我有一个 HashMap 将 Context 类的对象映射到整数。在Context类中,我确实重写了java.lang.Object的public int hashCode()和public boolean equals(Object c)。但是,我在迭代它时遇到问题:

我想要(例如)获取分配给每个 Context 对象的 Integer 值,因此我迭代映射的键集。但它不起作用,因为 map 说它没有指定的键:

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 一样。

我很困惑,我担心我错过了一些非常明显的东西,只是看不到它。如果是这样的话,我感到羞耻,但我仍然希望得到一个提示:-)

非常感谢!

最佳答案

如果您的 Context 对象以影响哈希码的方式可变,并且您在放置后执行了更改哈希码的操作,则可能会发生这种情况它在 map 上。映射只会记录插入点的 hashCode() 值,然后在您尝试查找特定键时使用该值来查找匹配项。 p>

如果您将哈希函数设置为常量,这将与其工作一致。基本上,您不应该在将哈希键放入映射后改变它们。

当然,这只是推测,但确实符合症状。

关于Java:HashMap 声称它有 key ,但不知何故没有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7235593/

相关文章:

python - 查找列表中不常见的元素

filter - 对抽象过滤器进行操作(列表理解): Combining two filters

java - 如何在 Struts 2 中进行动态 URL 重定向?

c++ - 处理迭代器时由信号 SIGSEGV(地址边界错误)终止

C++迭代器到集合的最后一个元素

arrays - swift 2.2 : Non +1 increasing iterator loops

Java设置范围内的迭代

java - 如何在 Tomcat 中使用数据源而无需编辑 context.xml?

java - 使用 Spring Security 的 IP 过滤器

java - 为什么我们不能在 Java 的 main 方法中将字段声明为 public?