相同字段的equals和hashcode不同

3
我同意这篇文章中的观点:在Java中重写equals和hashCode时应考虑哪些问题?

使用相同的字段来计算hashCode(),以便与计算equals()时使用的字段相同。

但我有一些疑问:
  • 这是否绝对必要?
  • 如果是,如果我不使用相同的字段会怎样?
  • 这会影响HashMap的性能或准确性吗?

1
你应该看一下这个链接:https://dev59.com/s3E95IYBdhLWcg3wi-ee - Hrishikesh
1
@Hrish,您不必要的格式化使链接无法被点击。 - rekire
好的,对此我很抱歉。我本来想将它作为答案发布,但实际上这并不能回答问题,所以我将其作为评论发布。让我修改一下。https://dev59.com/s3E95IYBdhLWcg3wi-ee - Hrishikesh
3个回答

3

是否有必要使用相同的字段?

是的,如果你不想出现任何意外情况。

如果我不使用相同的字段会怎样?

如果你使用了equals()方法,但没有使用相同的字段,那么对于相等的对象,你可能会得到不同的hashCode,这是equals和hashCode协定的要求。

例如,假设你有3个字段-abc。你使用ab进行equals()方法,并使用所有3个字段进行hashCode()方法。因此,对于2个对象,如果ab相等,而c不同,则两者将具有不同的哈希码,但仍然相等。

这会影响HashMap的性能或准确性吗?

这与性能无关,但是你的映射将不能按照预期运行。


实际上,equals 方法必须至少与 hashcode 方法一样具体,因此如果它与您的示例相反,那么问题并不大。将 hashcode 方法更粗略至少不会破坏合同和语义。因此,不具有相同字段不会在语义上导致意外情况。当然,我怀疑通常将它们设置为不同可能并不是一个好主意。 - Drunix
@Drunix 是的,在某些情况下,它不会真正影响语义。思路是,在hashCode中不要使用在equals()中不存在的字段。但正如你所说,理想情况下,我们应该使用相同的字段以保险起见。 - Rohit Jain

3
这些字段不必相同。要求是对于两个相等的对象,它们的哈希码必须相同。如果它们具有相同的哈希码,则不必相等。根据Javadoc:
- 如果在Java应用程序的执行期间多次调用它,则hashCode方法必须始终返回相同的整数值,只要在equals比较中使用的信息没有被修改即可。这个整数值不需要在同一应用程序的不同执行之间保持一致。 - 如果两个对象根据equals(Object)方法是相等的,则在每个对象上调用hashCode方法必须产生相同的整数结果。 - 如果两个对象根据equals(java.lang.Object)方法是不相等的,则不要求在每个对象上调用hashCode方法都产生不同的整数结果。然而,程序员应该知道为不相等的对象产生不同的整数结果可能会提高哈希表的性能。
例如,您可以始终返回1作为您的哈希码,并遵守哈希码协议,无论您在equals方法中使用了哪些字段。
始终返回1会提高hashCode的计算时间,但HashMap的性能会下降,因为它将更频繁地使用equals()方法。

0

在哈希码中使用的字段可以是等式中使用的字段的子集。 它仍然遵守这个规则:“每当a.equals(b)时,a.hashCode()必须与b.hashCode()相同”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接