General question: When implementing an override of the default equals
method in Java, what concerns should I have about simply utilizing an already implemented compareTo
method vs writing independent logic into the equals method? I noticed someone mention in another question that foo.equals((String)null)
returns false whereas String.compareTo((String)null)
throws a NullPointerException
. What makes these inconsistent results ideal functionality?
Sample equals
method:
@Override
public boolean equals(Object obj) {
if (obj != null && obj instanceof MyClass) {
MyClass msg = (MyClass)obj;
return this.compareTo(msg) == 0;
}
return false;
}
Edit: Quote from documentation on Comparable
The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C. Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false
Edit:
After further review, I find it of note that the Comparable documentation also states the following:
The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.)
Ergo, since null.compareTo(x)
obviously throws a NPE, x.compareTo(null)
should throw a NPE as well. Whereas for equals, that is not necessarily the case. I am pretty big on the proper handling of NPEs, so I find this relatively significant.
compareTo
may involve a lot more work than is necessary just to get an equality answer, which may end up being a performance issue, depending on your application usage.Other than that, following DRY principles it would be a good idea to re-use the code as you have suggested.
The difference between
equals()
andcompareTo()
is thatequals()
just checks if two objects are equal to each other where thecompareTo()
is used to identify the natural order of the instances of specified class. Alsoequals()
method has a contract withhashCode()
method butcompareTo()
hasn't.According to JavaDoc:
You can feel free to reuse
compareTo()
method logic in yourequals()
method but keep in mind all the contracts to theequals()
,hashCode()
and contract from JavaDoc forcompareTo()
method. If they do not conflict with each other then go ahead.I think that the enforcement of contracts is more important point.