Sobes.tech
Middle

Have you ever overridden the equals method yourself?

sobes.tech AI

Answer from AI

Yes, I have had to. Overriding equals() is necessary for correctly comparing objects based on their content, not just their reference.

Common reasons for overriding:

  • Value classes representing logically equal entities (e.g., Point, Date, custom DTOs).
  • Using objects in collections where comparison by value is important (e.g., HashSet, HashMap, `ArrayList.contains()).

When overriding equals(), you must follow the contract:

  1. Reflexivity: x.equals(x) should be true.
  2. Symmetry: If x.equals(y) is true, then y.equals(x) should also be true.
  3. Transitivity: If x.equals(y) is true and y.equals(z) is true, then x.equals(z) should also be true.
  4. Consistency: Multiple calls to x.equals(y) should return the same result if objects are not modified.
  5. Null comparison: x.equals(null) should be false.

Important: When overriding equals(), you must also override hashCode() to maintain the general contract between these methods. If two objects are equal according to equals(), their hashCode() must be the same. The reverse is not true.

Example of a basic override:

public class MyClass {
    private int id;
    private String name;

    // Constructor, getters, setters ...

    @Override
    public boolean equals(Object o) {
        if (this == o) return true; // Reflexivity
        if (o == null || getClass() != o.getClass()) return false; // Null check and type check

        MyClass myClass = (MyClass) o; // Type casting

        if (id != myClass.id) return false; // Primitive field comparison
        return name != null ? name.equals(myClass.name) : myClass.name == null; // Reference field comparison
    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + (name != null ? name.hashCode() : 0); // Hash code calculation based on fields
        return result;
    }
}

For more complex scenarios with fields of different types or collections, utility classes like Objects.equals() and Objects.hash() from Java java.util.Objects are used.

import java.util.Objects;

public class AnotherClass {
    private int value;
    private List<String> items;

    // Constructor, getters, setters ...

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AnotherClass that = (AnotherClass) o;
        // Using Objects.equals for null-safe comparison
        return value == that.value &&
               Objects.equals(items, that.items);
    }

    @Override
    public int hashCode() {
        // Using Objects.hash for hash code calculation
        return Objects.hash(value, items);
    }
}

Using IDEs to automatically generate equals() and hashCode() is common practice, but it is important to understand the generated code.