【问题标题】:Java: Modify id that changes hashcodeJava:修改改变哈希码的id
【发布时间】:2012-07-16 19:41:59
【问题描述】:

我使用HashSet,我需要修改一个对象的ID,但是它改变了hashcode并且破坏了HashSet和hashCode()方法的规则。

什么是最好的解决方案:从 Set 中删除对象并添加具有新 ID 的对象,或者在 Set 中的每个对象中保留哈希码(例如在构造函数中生成),或者有其他方法可以解决这个问题吗?

感谢您的帮助。

更新: 我犯了一个错误:在对象中保留哈希码是很糟糕的,因为在这种情况下,相同的对象可以有不同的哈希码。

【问题讨论】:

  • 你能覆盖hashCode,让它做你想做的事吗?
  • 根据定义,ID(entifier) 永远不应该在给定对象上改变。为什么允许对象的 ID 可变?
  • 好吧,当我修改我的 id 时,我无法生成相同的哈希码。
  • 是的,要走的路是 1. 从任何集合中移除对象 2. 对其进行变异 3. 将其放回原处。您最终可能会发现这样的对象已经存在,所以双重好你删除了它。
  • 这是因为我必须保留像 1,2,3 这样的 ID...,当我删除对象时,我会在必要时修改 ID。只是错了,是吗?

标签: java hashmap hashcode hashset


【解决方案1】:

作为容器的 HashSet 通过您放入其中的项目的哈希码访问其项目(包含、删除)。哈希码通常由其实例成员的状态构建。所以哈希码会随着对象状态的操作而改变。

Object 的文档说:“维护 hashCode() 方法的一般约定,其中规定相等的对象必须具有相等的哈希码”

如您所见,如果您更改保存在 HashSet 中的对象的状态,则该对象将无法再通过 remove 方法访问或通过 HashMap 的 contains 方法找到。

您提供的选项是:

  1. 删除对象,更改并再次添加 - 如果 HashSet 是强制性的,那么效果很好,最简单的方法

  2. 将哈希码的值保留在“某处” - 意味着,对于不相等的对象,您拥有相同的哈希码。或者,如果您遵守文档,您可能会遇到两个相等且具有相同哈希码的对象,但它们的成员变量不同!这可能会导致不可预知的错误。

【讨论】:

  • 最后一个选项绝对不正确。实际上,HashSet 是使用 HashMap 实现的。如果你改变一个包含对象的状态,HashMaps 和 HashSets 将会中断。
  • 可能是误会?如果你把一个对象放入一个 HashMap 并且你自己选择键(例如一个 int),那么你可以随意更改对象本身,只要你不更改键。所以关键不是(必然)绑定到对象状态...
  • 对。但是由于 OP 在将对象添加到 HashSet 后试图修改键。如果您的建议是键应该从对象中分离出来,并且对象应该是 HashMap 的值部分,那并不是真正解决同一个问题。
猜你喜欢
  • 1970-01-01
  • 2017-10-30
  • 2013-01-01
  • 2015-07-08
  • 2016-04-17
  • 1970-01-01
  • 2013-06-24
  • 2013-07-18
  • 1970-01-01
相关资源
最近更新 更多