Reputation: 4677
I am wondering if the implementation of ZonedDateTime.hashCode()
is guaranteed to be consistent with ZonedDateTime.isEqual(...)
? If not, then how can such a hash-code be computed?
EDIT
NOTE THAT THIS QUESTION IS ABOUT THE METHOD isEqual
, NOT ABOUT equals
. That is not a typographical error in my question.
EDIT #2
The reason I am asking this is because I have a class that contains a ZonedDateTime
object. The implementation of this class is as follows:
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.?, ...);
}
}
As you can see by the implementation, I am calling the isEqual
method within my implementation of equals
, since I want two objects to compare equal when the stored times point to the same instant. What can I put in my implementation of hashCode
, such that the Foo
class meets the requirement that hashCode
be consistent with equals
?
Upvotes: 1
Views: 759
Reputation: 7406
The isEqual()
method javadoc says
This is equivalent to using
dateTime1.toInstant().equals(dateTime2.toInstant());
.
So if you want to calculate a hashcode consistent with this method, you would have to use zdt.toInstant().hashCode()
. Then your Foo.hashCode()
would be consistent with your Foo.equals()
.
Upvotes: 4
Reputation: 44071
About your question regarding the method isEqual()
:
This method has nothing to do with the Object
-methods equals()
and hashCode()
. It should probably be better renamed to isSimultaneous()
in order to avoid confusion and to make the instant-only comparison clearer. Making a relationship of this similar-named method to consistency with hashCode()
is pointless.
Of course, if two ZonedDateTime
-objects have the same instant then the comparison based on isEqual()
will yield true
, but the hash codes are often different due to different local timestamps. You might consider this as inconsistency of hashCode()
with isEqual()
, but that is not the point.
The method isEqual()
is simply not relevant in any context where you use a hashmap-lookup.
In reverse, the method hashCode()
(or any computed hash-code) is not relevant if you use the method isEqual()
.
The reaction of so many downvoters (also my first misunderstanding of your question and your downvote shows that there is a lot of confusion potential in the fact that both methods (equals()
and isEqual()
) sound so similar but have very different meaning.
Upvotes: 2
Reputation: 140524
Read the source code of the two methods:
The isEqual
method compares ZonedDateTime
instances to see if they represent the same instant in time (i.e. equal seconds and equal nanoseconds since epoch).
The hashCode
method of ZonedDateTime
is computed by XOR-ing the hashcodes of the dateTime
, offset
and zone
.
There is no way that these two can be expected to be consistent, since they take into account very different properties of the instances.
Upvotes: 1