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 |
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);
}
}