【问题标题】:Java: HashMap claims it has key, but somehow hasn'tJava:HashMap 声称它有密钥,但不知何故没有
【发布时间】:2011-08-29 20:30:24
【问题描述】:

我有一个 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 一样。

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

非常感谢!

【问题讨论】:

  • 我应该指出,键集中只有一个元素,我知道设置存储元素没有特定的顺序:-)
  • 请发布您对 hashCode 和 equals 的覆盖,因为这可能是问题所在(怀疑是您的 equals--也许您的定义 a == b 与 b == a 不同?)

标签: java iterator set hashmap keyset


【解决方案1】:

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

如果您将散列函数设为常数,这将与它的工作一致。基本上,您不应该在将哈希键放入映射后对其进行变异。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    • 2019-07-20
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    相关资源
    最近更新 更多