ZonedDateTime是否为hashCode()与isEqual()一致?

时间:2016-03-24 19:59:23

标签: java datetime time java-8 java-time

我想知道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.?, ...);
    }
}

正如您在实现中所看到的,我在isEqual的实现中调用了equals方法,因为当存储的时间指向同一时刻时,我想要两个对象进行比较。我可以在hashCode的实施中加入哪些内容,以使Foo类符合hashCodeequals一致的要求?

3 个答案:

答案 0 :(得分:4)

isEqual()方法javadoc说

  

这相当于使用dateTime1.toInstant().equals(dateTime2.toInstant());

因此,如果要计算与此方法一致的哈希码,则必须使用zdt.toInstant().hashCode()。然后,您的Foo.hashCode()将与您的Foo.equals()保持一致。

答案 1 :(得分:2)

关于您的方法问题isEqual()

此方法与Object - 方法equals()hashCode()无关。它应该更好地重命名为isSimultaneous(),以避免混淆,并使即时比较更清晰。 将此类似名称的方法与hashCode()保持一致是毫无意义的。

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

方法isEqual()与使用hashmap-lookup的任何上下文无关。

相反,如果您使用方法hashCode()方法isEqual()(或任何计算的哈希码)无关紧要。

这么多吼叫者的反应(也是我对你的问题的第一次误解和你的downvote表明,两种方法(equals()isEqual())听起来都有很多混淆的可能性相似但意义却截然不同。

答案 2 :(得分:1)

阅读两种方法的源代码:

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

  • hashCode method of ZonedDateTime是通过对dateTimeoffsetzone的哈希码进行异或计算的。

这两者无法保持一致,因为它们考虑了实例的非常不同的属性。