Java › equals(), hashCode() & toString() Contracts
How does Comparable's compareTo() method relate to equals(), and what does it mean for compareTo() to be 'consistent with equals'?
IntermediateAnswer
compareTo() defines a class's natural ordering (used by sorting and by TreeMap/TreeSet), and being 'consistent with equals' means x.compareTo(y) == 0 should hold if and only if x.equals(y) is true -- this consistency is strongly recommended but not strictly enforced by the compiler, and violating it (as seen with a TreeSet using only salary-based compareTo() while equals() compares all fields) produces genuinely confusing behavior since TreeSet/TreeMap use compareTo() (not equals()) to determine element uniqueness, meaning such a collection's behavior would silently diverge from a HashSet/HashMap using the same class's equals()/hashCode(), a subtle but important consistency trap.
public class Employee implements Comparable<Employee> {
private final int salary;
private final String name;
@Override
public int compareTo(Employee other) {
int result = Integer.compare(salary, other.salary);
if (result != 0) return result;
return name.compareTo(other.name); // tiebreaker ensures compareTo()==0 implies genuinely equal
}
// equals()/hashCode() should compare the SAME fields (salary AND name) for true consistency
}Real-world example A payroll system's Employee class initially had a compareTo() considering only salary while equals() considered both salary and name, causing a HashSet<Employee> and a TreeSet<Employee> built from the identical data to report different element counts, a confusing inconsistency resolved by aligning compareTo() to break ties using the same fields equals() considers.