【问题标题】:Java Hash Map containsKey is returning true when it should notJava Hash Map containsKey 在不应该返回 true 时
【发布时间】:2012-11-15 06:01:16
【问题描述】:

所以我有这个方法可以将对象添加到显示中。首次打开显示时,所有现有对象都会被 1 个 1 添加到 HashMap 中。之后用户可以添加更多,一次添加 1 个,这会将新对象放入 HashMap。

Key 是 Object,Value 是一个自定义类,其中包含 Object 和一些关于它的其他变量。

这一切都很好,但是当显示器关闭并打开一个新实例时,它应该重新加载所有对象(包括用户在使用期间创建和保存的对象),但出于某种原因新创建的,在执行 containsKey 时会发现不正确的匹配项。

我真的不明白为什么它不应该找到匹配项。当我执行 containsValue 时,它​​没有找到任何不正确的匹配项(它应该正常工作)但它没有帮助,因为当我使用 HashMap.put(K, V) 时,它会覆盖它会为 containsKey 返回误报的匹配项.

代码所做的只是遍历每个对象,检查 HashMap 是否已经包含键,如果包含则返回键的值,否则根据传递给方法的键创建一个值并将其放入哈希图。

很抱歉,我无法发布代码,所以如果您没有它就无法提供帮助,我理解,但这是为了工作,我不确定是否可以发布代码,即使它只是一个 sn -p。

任何帮助或指导将不胜感激,我仍在谷歌上搜索以查看是否可以找到任何信息。

编辑:我找到了解决方案。 hashcode 函数返回的值本质上是一个索引。问题是它在初始对象之后被重置,因此新添加的对象将从零开始覆盖现有对象。我修改了哈希码及其工作方式。

感谢大家的帮助。

【问题讨论】:

  • 如果是为了工作,那就不要贴实际代码了,但是可以写个小代码sn-p,演示一下你实际在做什么。
  • 我发布了我认为重要部分的修改后的 sn-p。
  • @user18554575.. 你的node.getUserObject 返回什么?
  • 只是与节点关联的对象。本质上,它应该与 Object 类相同,但没有父类 isFilterGroup 和 isThecurrentEnum 。
  • 关于您的编辑:这不是完整的修复。 hashCode 的不同值将阻止 HashMap 将两个对象视为相等,但 HashMap 总是 也会检查 equals 方法。因此,如果更改 hashCode 似乎可以解决问题,那么这意味着您的 equals 方法也已损坏,仍然需要修复!

标签: java hash map false-positive containskey


【解决方案1】:

我建议您不要使用自定义对象作为 HashMap 的键。

这些物体有一些标识吗?某些属性不会从一个对象重复到另一个对象?把HashMap的key改成这个属性。

这样您就可以使用.containsKey() 将此属性作为参数传递。

【讨论】:

  • 当提示添加新名称时,它们必须具有唯一名称。我可以尝试将其更改为此,但我必须查看代码周围的一些基础架构。
【解决方案2】:

似乎您已经覆盖了 equals 方法,但没有覆盖您班级中的 hashCode 方法。

请注意,如果您使用 custom class 对象作为 HashMap 中的键,请确保您的类同时覆盖 equalshashCode 方法,否则您将永远无法找到 @987654327 @在HashMap再次。

如果您覆盖equals 而不是hashCode,那么您的keys 可能基于您的equals 方法相等,但它的hashCode 将由Object 类的hashCode 方法生成方法,为您的实例生成不同的 hashCode。

一般来说,如果您应该覆盖both equals and hashCode 方法或override none of them。此外,为了计算hashCodes,您应该只使用那些在equals 方法中用于比较的属性。

此外,作为其中一个 cmets,您应该确保您的 Keys 是不可变的。

【讨论】:

  • 另外,键应该是不可变的——如果你改变一个用作键的对象的状态,从而影响equalshashCode的结果,映射就会混淆你会得到不可预知的结果。
  • 回复:“好像你没有在你的班级中覆盖 equalshashCode 方法”:我认为你有那个落后。看起来这个类已经覆盖了这些方法;如果没有,那么HashMap 将有效地成为IdentityHashMap,而containsKey 永远不会返回任何误报。
  • @ruakh.. 是的,实际上我错过了。编辑了我的 psot。
  • 自定义类是值。顶级“对象”类是关键。
  • @user1855475。请在您的问题中也发布一些代码,以便我们清楚您做了什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-01
  • 2019-03-29
  • 1970-01-01
相关资源
最近更新 更多