ZonedDateTime hashCode() 和 isEqual() 是否一致?

Is ZonedDateTime hashCode() Consistent with isEqual()?

请问ZonedDateTime.hashCode()的实现是否保证与ZonedDateTime.isEqual(...)一致?如果不是,那么如何计算这样的哈希码?

编辑

请注意,此问题是关于方法 isEqual,而不是关于 equals。这不是我问题中的印刷错误。

编辑 #2

我问这个的原因是因为我有一个包含 ZonedDateTime 对象的 class。这个class的实现如下:

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 class 满足 hashCodeequals 一致的要求?

关于你关于方法的问题 isEqual():

此方法与 Object 方法 equals()hashCode() 无关。最好将其重命名为 isSimultaneous() 以避免混淆并使仅即时比较更清晰。 将这种同名方法与 hashCode() 联系起来是没有意义的。

当然,如果两个ZonedDateTime-对象具有相同的时刻,那么基于isEqual()的比较将产生true,但是由于不同的地方,哈希码通常是不同的时间戳。您可能认为这是 hashCode()isEqual() 的不一致,但这不是重点。

方法 isEqual() 与使用散列映射查找的任何上下文都不相关。

相反,如果您使用方法 isEqual().[=26,则方法 hashCode()(或任何计算的哈希码)不相关=]

这么多反对者的反应(也是我对你的问题和你的反对票的第一个误解表明这两种方法(equals()isEqual())听起来很相似,但含义却大不相同。

阅读两种方法的源码:

  • isEqual method 比较 ZonedDateTime 个实例,看它们是否代表同一时刻(即自纪元以来相等的秒数和相等的纳秒数)。

  • hashCode method of ZonedDateTime 是通过对 dateTimeoffsetzone.

    [ 的哈希码进行异或计算得出的=30=]

不可能期望这两者是一致的,因为它们考虑了非常不同的实例属性。

isEqual() 方法 javadoc 说

This is equivalent to using dateTime1.toInstant().equals(dateTime2.toInstant());.

所以如果你想计算一个符合这种方法的哈希码,你就必须使用zdt.toInstant().hashCode()。那么你的 Foo.hashCode() 将与你的 Foo.equals().

一致