Comparable Without equals() Override

ID

java.comparable_must_override_equals

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

CWE:581, reliability

Description

Reports classes that implement Comparable but do not override equals(Object).

Rationale

The general contract of Comparable strongly recommends that compareTo be consistent with equals. If compareTo returns zero for two objects but equals returns false, collections like TreeSet and TreeMap may behave inconsistently with HashSet and HashMap. This leads to subtle, hard-to-diagnose bugs.

// Bad -- Comparable without equals
public class Score implements Comparable<Score> {
    private int value;

    public int compareTo(Score other) {
        return Integer.compare(this.value, other.value);
    }
    // equals() not overridden -- uses identity comparison
}

Remediation

Override equals(Object) (and hashCode()) so that the equality check is consistent with the ordering defined by compareTo.

// Good
public class Score implements Comparable<Score> {
    private int value;

    public int compareTo(Score other) {
        return Integer.compare(this.value, other.value);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Score)) return false;
        return value == ((Score) o).value;
    }

    @Override
    public int hashCode() {
        return Integer.hashCode(value);
    }
}