Jeff G
Jeff G

Reputation: 4677

Is ZonedDateTime hashCode() Consistent with isEqual()?

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

Answers (3)

dcsohl
dcsohl

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

Meno Hochschild
Meno Hochschild

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

Andy Turner
Andy Turner

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

Related Questions