【问题标题】:Can I implement hashCode and equals this way for (Hash)Sets?我可以为 (Hash)Sets 实现 hashCode 和 equals 这种方式吗?
【发布时间】:2014-10-08 11:43:10
【问题描述】:

我知道如果a.equals(b),我们必须有a.hashCode() == b.hashCode(),否则我们会得到奇怪的结果,但我想知道是否也需要反过来。

更具体地说,我有一个hashCode() 函数,它使用字段 id 来计算 hashCode。但是,我的 equals() 函数只使用简单的比较 "==" 来检查是否相等。这可能看起来很奇怪,但除非需要更多细节,否则这就是我实现它的方式。

现在的问题是这会搞砸什么吗?专门针对 HashSet,但更普遍的是,针对 Set 的任何(常见)实现。

按照我的理解,Set 将首先检查 hashCode,然后是 equals 运算符,以查看是否存在重复对象。在这种情况下,它应该可以正常工作吗?如果两个对象是同一个实例,它们将产生相同的 hashCode 并为 equals() 返回 true,因此 Set 只允许添加一次实例。

对于具有相同 id 的两个独立实例,hashCode 将相同,但 equals() 运算符将返回 false,从而允许两个对象进入 Set,这是我希望完成的。

这是初学者的错误吗?我错过了什么吗?这会对 Set 以外的任何集合类型产生意外结果吗?


编辑:

我想我应该解释一下自己。我有一个 Hibernate 对象 FooReference,它使用 id 实现了 hashCode 和 equals 方法。保证此对象始终具有唯一 ID。然而,在这个对象被持久化之前,我使用了一个默认 id 为 -1 的 Foo 对象。因此,当将其放入 Set (要保存)时,我知道每个 Foo 都是唯一的(因此是基本的 == 运算符)。所以这个扩展了 FooReference 的 Foo 用一个基本的 == 覆盖了 equals 方法。就我的目的而言,这应该可行……希望如此。

【问题讨论】:

  • 为什么要覆盖equals,使其调用==,而这正是Object 中定义的equals 所做的事情?
  • 因为我的对象扩展了另一个对象,其中equals()方法比默认的equals()方法更复杂。

标签: java hashset


【解决方案1】:

允许对象具有相同的哈希码,但彼此不相等。事实上,将hashCode 实现为简单的return 0 是完全有效的(尽管效率低下且是个坏主意),并为每个 实例提供相同的哈希码。

只要两个对象相等(由equals 方法确定),它们就具有相同的哈希码。

但是,如果您的 equals 方法只是在内部使用 == 比较两个对象,则没有两个(不同的)实例将彼此相等,因此定义您自己的 hashCodeequals 毫无意义方法。默认实现将产生相同的行为。

【讨论】:

  • 请查看我更新的问题。我正在考虑使用 if 语句,如果 id == -1 我使用简单的 == 运算符。否则 equals() 也将基于 id。
  • 这样所有ID为-1的(不同的)实例彼此不相等,但其他ID的实例可以相等吗?是的,你可以这样做。对于 ID 为 -1 的所有实例来说,拥有相同的哈希码不是问题(尽管如果有大量的 HashSet 中添加/删除项目,您可能会看到性能不佳)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多