我想知道ZonedDateTime.hashCode()
的实现是否保证与ZonedDateTime.isEqual(...)
一致? 如果不是,那么如何计算这样的哈希码?
编辑
请注意,这个问题是关于方法isEqual
,而不是关于equals
。 在我的问题中,这不是印刷错误。
编辑#2
我问这个问题的原因是因为我有一个包含ZonedDateTime
对象的类。 此类的实现如下所示:
public class Foo {
private ZonedDateTime dateTime;
@Override
public boolean equals(Object obj) {
// Boilerplate stuff here...
final Foo other = (Foo)obj;
return (... && dateTime.isEqual(other.dateTime) && ...);
}
@Override
public int hashCode() {
// What do I need to put here so that my implementation of
// hashCode is consistent with my implementation of equals?
return Objects.hashCode(..., dateTime.?, ...);
}
}
正如您在实现中看到的那样,我在equals
实现中调用isEqual
方法,因为我希望当存储的时间指向同一时刻时,两个对象进行比较。 我可以在hashCode
的实现中放什么,以使Foo
类满足hashCode
与equals
一致的要求?
javadoc 说的isEqual()
方法
这相当于使用
dateTime1.toInstant().equals(dateTime2.toInstant());
.
因此,如果要计算与此方法一致的哈希码,则必须使用 zdt.toInstant().hashCode()
.那么你的Foo.hashCode()
将与您的Foo.equals()
一致。
关于您关于方法的问题 isEqual()
:
此方法与Object
方法无关 equals()
和 hashCode()
。可能应该更好地将其重命名为isSimultaneous()
以避免混淆并使仅即时比较更清晰。将这种名称相似的方法与hashCode()
保持一致性联系起来是没有意义的。
当然,如果两个ZonedDateTime
对象具有相同的时刻,那么基于isEqual()
的比较将产生true
,但由于本地时间戳不同,哈希码通常不同。您可能会认为这是hashCode()
与isEqual()
不一致,但这不是重点。
方法isEqual()
在您使用哈希图查找的任何上下文中都无关紧要。
相反,如果使用方法 isEqual()
,则方法 hashCode()
(或任何计算的哈希代码(无关紧要。
这么多反对者的反应(也是我对你的问题和你的反对票的第一次误解(表明,这两种方法(equals()
和isEqual()
(听起来如此相似但具有非常不同的含义,这一事实存在很多混淆的可能性。
阅读两种方法的源代码:
-
isEqual
方法比较ZonedDateTime
实例,以查看它们是否表示相同的时刻(即自纪元以来的相等秒和相等纳秒(。 -
ZonedDateTime
的hashCode
方法是通过对dateTime
、offset
和zone
的哈希码进行异或运算来计算的。
两者不可能是一致的,因为它们考虑了实例的非常不同的属性。