Sobes.tech
Middle

What are the rules for overriding hashCode and equals methods in Java?

sobes.tech AI

Answer from AI

For the correct operation of collections and other mechanisms based on object comparison (e.g., HashMap, HashSet), the following rules must be observed:

  1. Reflexivity (equals): For any non-null reference x, x.equals(x) should return true.
  2. Symmetry (equals): For any non-null references x and y, x.equals(y) should return true only if y.equals(x) returns true.
  3. Transitivity (equals): For any non-null references x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  4. Consistency (equals): For any non-null references x and y, multiple calls to x.equals(y) should consistently return true or false, provided no information used in comparisons has been modified.
  5. equals and null: For any non-null reference x, x.equals(null) should return false.
  6. Consistency between equals and hashCode: If x.equals(y) returns true for any two non-null references x and y, then x.hashCode() should return the same value as y.hashCode().
  7. Consistency of hashCode: Multiple calls to hashCode() for the same object during the execution of an application should consistently return the same integer value, provided no information used in equals comparisons on the object has been modified. (It is not required to return the same value across different runs of the application).

Here is an example implementation:

class Person {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public boolean equals(Object o) {
        // Adhere to null and reflexivity rules
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        // Cast types
        Person person = (Person) o;
        // Compare significant fields
        return age == person.age &&
               Objects.equals(name, person.name); // Use Objects.equals for null-safe string comparison
    }

    @Override
    public int hashCode() {
        // Generate hash code based on significant fields
        return Objects.hash(name, age); // Use Objects.hash for convenience and correctness
    }
}