没有hashCode()的equals()方法

7

如果我只需要比较对象,而且还没有计划将对象放入任何基于哈希的容器中,那么我是否只能实现equals()而不是hashCode()?

似乎所有的Java圣经都说这两个方法必须一起实现。 :(

我的担忧是: -如果我总是一起实现hashCode()和equals(),那么有很多代码实际上是没有用的,并且没有单元测试覆盖。 (如果不使用hashCode(),我不打算进行单元测试) -只有当我将对象放入基于哈希的容器中时,我才知道对象的查找方式。只有在那时,我才能确定使用哪种哈希策略。


关于您的问题:您可能想要使用https://github.com/jqno/equalsverifier自动测试等式/哈希码合同。 - raphaëλ
使代码符合对象规范的简单方法是从hashCode返回相同的常量值。虽然这不是理想的做法(即如果用作哈希时会产生错误的冲突),但它永远不会“失败”,因为合同得到了遵守。 - user2864740
7个回答

10
您可以这样做,但是您将会违反equals通用合同:

如果两个对象根据equals(Object)方法是相等的,则在两个对象上调用hashCode方法必须产生相同的整数结果。

...这将导致奇怪的错误。即使您认为自己没有使用哈希码,任何您传递对象给的外部代码都可能依赖于它们,即使它似乎不是基于哈希的。如果您不打算给您的对象一个合理的哈希方法,至少让它抛出一个运行时异常。然而,最好还是给您的对象一个合理的hashCode。


5

Oracle的教程解答了这个问题。

hashCode()方法

根据定义,如果两个对象相等,则它们的哈希码也必须相等。如果您重写了equals()方法,则会更改比较两个对象的方式,而Object类中hashCode()方法的实现将不再有效。因此,如果您重写了equals()方法,则还必须重写hashCode()方法。


4
只要不是必须实现hashCode,每当您实现equals时,您必须还要实现hashCode。
如果您没有这样做,您最终将得到损坏的对象。为什么?对象的hashCode方法必须考虑与其equals方法相同的字段。通过重写equals方法,您声明某些对象等于其他对象,但原始的hashCode方法将所有对象视为不同。因此,您将拥有具有不同哈希码的相等对象。例如,在HashMap上调用contains()将返回false,即使已添加该对象。

2

我只需要实现equals()方法而不用实现hashCode()方法吗?

是的,你可以。因为它们只是父类Object中的两个方法,所以实现与否完全由你决定(可以同时实现或单独实现)。

所有Java圣经都说这两个必须一起实现。

如果你没有使用任何涉及hashcode(如哈希容器)的内容,那么这不是一个必须的步骤。但是,为了避免出现意外情况,最好一起实现它们。


1

从技术上讲,你可以只实现equals()方法而不实现hashcode()方法。

但这将是一种违约行为

标准做法是应该同时实现它们,并且对于相等的对象,它们的hashcode应该相同。


这个答案被谷歌选为正确答案 =D - Klesun

0

是的,你可以,但是推荐吗?不推荐

所有的书都说,如果equals返回true,则hashcode必须相同,这样才会成立。但是,最好为自己的实例进一步指定,就像你对equals所做的那样。


0

显然,你可以不使用哈希,但是你不打算使用哈希并不足以成为不实现它的理由。你使用的一些库可能会使用哈希。如果你想避免测试equals或hashcode,你可以尝试自动生成这些方法(大多数IDE都有这个功能),或者使用project lombok(https://projectlombok.org)。


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