hashCode() vs equals() in Java

1. Introduction

In Java, hashCode() and equals() are two fundamental methods from the Object class used for object comparison and hashing. The hashCode() method provides a unique integer representation of an object, primarily used in hash-based collections like HashMap. The equals() method determines the equality of two objects based on their state.

2. Key Points

1. hashCode() returns an integer that represents the object's memory address by default.

2. equals() method is used to check if two objects are the same in terms of their state.

3. Consistency between equals() and hashCode() is important: if two objects are equal according to the equals(Object) method, then calling hashCode() on each of the two objects must produce the same integer result.

4. hashCode() is used in hashing to decide where to store the object in memory, while equals() determines the actual equality of two objects.

3. Differences

hashCode() equals()
Computes an integer representation of the object. Checks if two objects are the same in terms of their content.
Used in organizing objects in collections like HashMap. Used to compare objects to see if they are logically equal.
If two objects are equal, they must have the same hash code. Two objects can have the same hash code without being equal.
Mostly auto-generated by the object’s memory address, but it can be customized. By default, checks if two references point to the same object, but can be overridden to check the actual data.
Does not need to be overridden if equals() is not overridden. It should be overridden in every class that overrides equals() to maintain the contract with hashCode().
It’s possible for two objects to have the same hash code without being equal. However, the opposite is not true (if two objects are equal, they must have the same hash code). Two objects can only be considered equal if the equals() method returns true, reflecting that they are logically identical in the context of the application.

4. Example

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Overriding equals() method to compare two Person objects based on their properties
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && name.equals(person.name);
    }

    // Overriding hashCode() to be consistent with how we defined equals()
    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age;
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        Person person1 = new Person("John", 30);
        Person person2 = new Person("John", 30);

        // Same state, so equals() should return true
        System.out.println("person1.equals(person2): " + person1.equals(person2));

        // Consistent hashCode, because person1 equals person2
        System.out.println("person1.hashCode() == person2.hashCode(): " + (person1.hashCode() == person2.hashCode()));
    }
}

Output:

person1.equals(person2): true
person1.hashCode() == person2.hashCode(): true

Explanation:

1. The Person class overrides the equals() method to compare objects by their name and age.

2. It also overrides hashCode() to ensure that the hash code is consistent with the equals() method.

3. When two Person objects have the same name and age, equals() returns true, and their hash codes are the same.

5. When to use?

- Override equals() when you need to define a custom equality check between two objects.

- Override hashCode() whenever equals() is overridden to maintain the general contract for the hashCode() method, which states that equal objects must have equal hash codes.

Comments