Search code examples
javahashmapequalshashcode

In Java, during Object#equals() call, do both objects necessarily have same hashCode ? Do we need to ever compare hashCode within equals()?


I have read somewhere, in context of HashMap : hashCode() allows sorting objects by their hash values, and then the Object#equals method only needs to be invoked when objects share the same hash value.

Does it mean that when eventually equals() method is called , then hashCode was already compared and found to be necessarily equal? Is there any exception for this scenario?

2nd part of question: Will it ever make sense to check hashCode() of both objects in equals() method ?

public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj == null) {
            return false;
        }

        if (!(obj instanceof InternalObjectSerialized)) {
            return false;
        }
        InternalObjectSerialized<?> inputObj = (InternalObjectSerialized<?>) obj;

        if (!(Arrays.equals(this.bytes, inputObj.bytes))) {
            return false;
        }

        // Does the following line make any sense ??
        return this.hashCode() == inputObj.hashCode();
    }

Solution

  • To summarize from the comments:

    In Java, during Object#equals() call, do both objects necessarily have same hashCode?

    Two objects that are .equals to each other do need to have the same hashCode, but it is up to you to write the equals method and the hashCode method to make sure this is true.

    • Two objects can have the same hashCode and not be equal, because of hash collisions.
    • Two objects that are equal must generate the same hashCode.

    When a HashMap calls equals() on two key objects, has it first ensured that the hash codes are equal? Probably, but not guaranteed and it’s an implementation detail that we should not need to know about. Also the implementation of HashMap has changed more than once over the Java versions and may change again, so the answer may depend on Java version. You may inspect the source code of HashMap in your Java version to see.

    The HashMap distributes the key-value pairs into so-called buckets based on the hash code of the key. In case of a collision — two or more pairs landing in the same bucket — it may conceivably compare keys belonging in the same bucket for equality. Since there are many more possible hash codes than there are buckets, this could mean also sometimes comparing objects with different hash codes using equals().

    Other kinds of Map such as a TreeMap probably don't use hash codes at all.

    Do we need to ever compare hashCode within equals()?

    No, you do not need to compare hashCodes in your implementation of .equals, in fact you should not do that.