Phase 10 of 20 · Topic 10.5

Object Class Root: equals(), hashCode() & toString() Contract

1Concept

`java.lang.Object` is the root of the entire Java class hierarchy. The equals/hashCode contract dictates: If two objects are equal according to `equals()`, they MUST produce the exact same `hashCode()`. Failing this contract corrupts HashMaps and HashSets.

2Architecture Diagram

Object Contract:
  objA.equals(objB) == true  =====>  objA.hashCode() MUST EQUAL objB.hashCode()
  objA.hashCode() == objB.hashCode() =====> objA may or may not equal objB (Hash Collision)

3Code Example

Core Java
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

public class ObjectContractDemo {
    static class Employee {
        int id;
        String name;

        Employee(int id, String name) {
            this.id = id;
            this.name = name;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Employee e)) return false;
            return id == e.id && Objects.equals(name, e.name);
        }

        @Override
        public int hashCode() {
            return Objects.hash(id, name);
        }

        @Override
        public String toString() {
            return "Employee[id=" + id + ", name=" + name + "]";
        }
    }

    public static void main(String[] args) {
        Set<Employee> team = new HashSet<>();
        Employee e1 = new Employee(101, "Alice");
        Employee e2 = new Employee(101, "Alice");

        team.add(e1);
        team.add(e2);
        System.out.println("HashSet Size: " + team.size() + " (Deduplicated correctly!)");
        System.out.println("Employee representation: " + e1);
    }
}

4Expected Output

HashSet Size: 1 (Deduplicated correctly!)
Employee representation: Employee[id=101, name=Alice]

5Key Takeaways

  • Always override `hashCode()` whenever you override `equals()`.
  • Use `java.util.Objects.hash()` and `Objects.equals()` for clean null-safe implementations.
  • Never use non-deterministic fields (like timestamps) in equals/hashCode.