如果我只需要比较对象而不打算将对象放入任何基于散列的容器中,我是否只能实现equals()而不是hashCode()?
似乎所有Java圣经都说这两个必须一起实现。 :(
我的担忧: - 如果我总是和equals()一起实现hashCode(),那么会有很多代码没有真正使用,并且没有单元测试覆盖。 (如果不使用,我不打算单元测试hashCode()) - 直到我将对象放入基于散列的容器中时才知道如何查找对象。直到那时我才能确定使用哪种散列策略。
答案 0 :(得分:6)
你可以,但是你违反了equals
的一般合同,这将导致奇怪的错误。即使您不认为您正在使用哈希码,您传递对象的任何外部代码都可能依赖于它们,即使它似乎不是基于哈希的。如果你不打算给你的对象一个合适的哈希方法,至少让它抛出一个运行时异常。但是,为对象提供合适的hashCode几乎总是更好。
答案 1 :(得分:2)
我可以只实现equals()而不是hashCode()吗?
是的你可以。因为它们只是来自父类Object
的方法,所以它实际上是你选择实现或不实现(一起或个人)。
All Java bibles say these two MUST be implemented together.
如果您没有使用与hashcode
相关的任何内容(正如您所说的基于哈希的容器),那么它不是MUST
,但是将它们一起实施以避免任何意外情况是一种很好的做法。< / p>
答案 2 :(得分:2)
只要不是强制实现hashCode,每当你实现equals时,你还必须实现hashCode
如果你没有这样做,你最终会遇到破碎的物体。为什么?对象的hashCode方法必须将与其equals方法相同的字段考虑在内。通过重写equals方法,您将某些对象声明为与其他对象相同,但原始的hashCode方法将所有对象视为不同的对象。因此,您将拥有具有不同哈希码的相等对象。例如,即使已添加对象,在HashMap上调用contains()也将返回false。
答案 3 :(得分:2)
Oracle教程answers这个
hashCode()方法
根据定义,如果两个对象相等,则它们的哈希码也必须相等。如果重写equals()方法,则更改两个对象的等效方式,并且对象的hashCode()实现不再有效。因此,如果重写equals()方法,则还必须覆盖hashCode()方法。
答案 4 :(得分:0)
是的,你可以,但是推荐吗?无
所有书籍都说,如果equals返回true,则哈希码必须相同,这将是如此。但是,最好为你自己的实例进一步指定它,就像你使用equals一样。
答案 5 :(得分:0)
是的,你只能在不实现hashcode()方法的情况下实现equals()方法。
但标准做法是说你应该实现它们,对于相同的对象,哈希码应该是相同的。
答案 6 :(得分:0)
嗯,显然你可以,但你不打算使用散列的事实并不是不实现它的充分理由。您使用的某些库可以使用散列。如果你想避免测试equals或hashcode,你可以尝试自动生成这些方法(大多数IDE都有这个功能),或者使用项目lombok(https://projectlombok.org)