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 满足 hashCode
与 equals
一致的要求?
关于你关于方法的问题 isEqual()
:
此方法与 Object
方法 equals()
和 hashCode()
无关。最好将其重命名为 isSimultaneous()
以避免混淆并使仅即时比较更清晰。 将这种同名方法与 hashCode()
联系起来是没有意义的。
当然,如果两个ZonedDateTime
-对象具有相同的时刻,那么基于isEqual()
的比较将产生true
,但是由于不同的地方,哈希码通常是不同的时间戳。您可能认为这是 hashCode()
与 isEqual()
的不一致,但这不是重点。
方法 isEqual()
与使用散列映射查找的任何上下文都不相关。
相反,如果您使用方法 isEqual()
.[=26,则方法 hashCode()
(或任何计算的哈希码)不相关=]
这么多反对者的反应(也是我对你的问题和你的反对票的第一个误解表明这两种方法(equals()
和 isEqual()
)听起来很相似,但含义却大不相同。
阅读两种方法的源码:
isEqual
method 比较 ZonedDateTime
个实例,看它们是否代表同一时刻(即自纪元以来相等的秒数和相等的纳秒数)。
hashCode
method of ZonedDateTime
是通过对 dateTime
、offset
和 zone
.
[ 的哈希码进行异或计算得出的=30=]
不可能期望这两者是一致的,因为它们考虑了非常不同的实例属性。
isEqual()
方法 javadoc 说
This is equivalent to using dateTime1.toInstant().equals(dateTime2.toInstant());
.
所以如果你想计算一个符合这种方法的哈希码,你就必须使用zdt.toInstant().hashCode()
。那么你的 Foo.hashCode()
将与你的 Foo.equals()
.
一致
请问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 满足 hashCode
与 equals
一致的要求?
关于你关于方法的问题 isEqual()
:
此方法与 Object
方法 equals()
和 hashCode()
无关。最好将其重命名为 isSimultaneous()
以避免混淆并使仅即时比较更清晰。 将这种同名方法与 hashCode()
联系起来是没有意义的。
当然,如果两个ZonedDateTime
-对象具有相同的时刻,那么基于isEqual()
的比较将产生true
,但是由于不同的地方,哈希码通常是不同的时间戳。您可能认为这是 hashCode()
与 isEqual()
的不一致,但这不是重点。
方法 isEqual()
与使用散列映射查找的任何上下文都不相关。
相反,如果您使用方法 isEqual()
.[=26,则方法 hashCode()
(或任何计算的哈希码)不相关=]
这么多反对者的反应(也是我对你的问题和你的反对票的第一个误解表明这两种方法(equals()
和 isEqual()
)听起来很相似,但含义却大不相同。
阅读两种方法的源码:
isEqual
method 比较ZonedDateTime
个实例,看它们是否代表同一时刻(即自纪元以来相等的秒数和相等的纳秒数)。
[ 的哈希码进行异或计算得出的=30=]hashCode
method ofZonedDateTime
是通过对dateTime
、offset
和zone
.
不可能期望这两者是一致的,因为它们考虑了非常不同的实例属性。
isEqual()
方法 javadoc 说
This is equivalent to using
dateTime1.toInstant().equals(dateTime2.toInstant());
.
所以如果你想计算一个符合这种方法的哈希码,你就必须使用zdt.toInstant().hashCode()
。那么你的 Foo.hashCode()
将与你的 Foo.equals()
.