equals()没有hashCode()

如果我只需要比较对象而不打算将对象放入任何基于散列的容器中,我可以只实现equals()而不是hashCode()吗?

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

我关注的是: – 如果我总是和equals()一起实现hashCode(),那么会有很多代码没有真正使用,并且没有unit testing覆盖。 (如果不使用的话,我不打算unit testinghashCode()) – 只有当我将对象放入基于散列的容器中时才会知道如何查找对象。 直到那时我才能确定使用哪种散列策略。

你可以,但你将违反equals的一般合同,这将导致奇怪的错误。 即使你不认为你正在使用哈希码,你传递对象的任何外部代码也可能依赖于它们,即使它似乎不是基于哈希的。 如果你不打算给你的对象一个合适的哈希方法,至少让它抛出一个运行时exception。 但是,为对象提供一个不错的hashCode几乎总是更好。

只要不是强制实现hashCode, 每当你实现equals时,你还必须实现hashCode

如果你没有这样做,你最终会得到破碎的物体。 为什么? 对象的hashCode方法必须将相同的字段考虑为equals方法。 通过重写equals方法,您将某些对象声明为与其他对象相同,但原始的hashCode方法将所有对象视为不同的对象。 因此,您将拥有具有不同哈希码的相等对象。 例如,即使已添加对象,在HashMap上调用contains()也将返回false。

我可以只实现equals()而不是hashCode()吗?

是的你可以 。 因为它们只是来自父类Object ,所以它实际上是你选择实现或不实现(一起或个人)。

All Java bibles say these two MUST be implemented together.

如果你没有使用与hashcode相关的任何东西(正如你所说的基于散列的容器),它不是MUST ,但是将它们一起实现以避免任何意外情况是一个好习惯。

Oracle的教程回答了这个问题

hashCode()方法

根据定义,如果两个对象相等,则它们的哈希码也必须相等。 如果重写equals()方法,则更改两个对象的等效方式,并且Object的hashCode()实现不再有效。 因此,如果重写equals()方法,则还必须覆盖hashCode()方法。

是的,你可以,但是推荐吗? 没有

所有书籍都说,如果equals返回true,则哈希码必须是相同的,这将是如此。 但是,最好为您自己的实例进一步指定它,就像您使用equals一样。

嗯,显然你可以,但你不打算使用散列的事实并不是不实现它的充分理由。 您使用的某些库可以使用散列。 如果你想避免测试equals或hashcode,你可以尝试自动生成这些方法(大多数IDE都有这个function),或者使用项目lombok( https://projectlombok.org

是的,您只能在不实现hashcode()方法的情况下实现equals()方法。

但是标准实践表明你应该实现它们,对于相同的对象,哈希码应该是相同的。