When testing for equality of String
's in Java I have always used equals()
because to me this seems to be the most natural method for it. After all, its name already says what it is intended to do. However, a colleague of mine recently told me had been taught to use compareTo() == 0
instead of equals()
. This feels unnatural (as compareTo()
is meant to provide an ordering and not compare for equality) and even somewhat dangerous (because compareTo() == 0
does not necessarily imply equality in all cases, even though I know it does for String
's) to me.
He did not know why he was taught to use compareTo()
instead of equals()
for String
's, and I could also not find any reason why. Is this really a matter of personal taste, or is there any real reason for either method?
There are certain things which you need to keep in mind while overriding compareTo in Java e.g. Compareto must be consistent with equals and subtraction should not be used for comparing integer fields as they can overflow. check Things to remember while overriding Comparator in Java for details.
A very important difference between compareTo and equals:
equals() checks if two objects are the same or not and returns a boolean.
compareTo() (from interface Comparable) returns an integer. It checks which of the two objects is "less than", "equal to" or "greater than" the other. Not all objects can be logically ordered, so a compareTo() method doesn't always make sense.
Note that equals() doesn't define the ordering between objects, which compareTo() does.
Now I advise you to review the source code of both methods to conclude that equals is preferable over compareTo that involves some Math calculations.
equals()
should be the method of choice in the case of the OP.Looking at the implementation of
equals()
andcompareTo()
in java.lang.String on grepcode, we can easily see that equals is better if we are just concerned with the equality of two Strings:equals()
:and
compareTo()
:When one of the strings is a prefix of another, the performance of
compareTo()
is worse as it still needs to determine the lexicographical ordering whileequals()
won't worry any more and return false immediately.In my opinion, we should use these two as they were intended:
equals()
to check for equality, andcompareTo()
to find the lexical ordering.Here one thing is important while using
compareTo()
overequals()
thatcompareTo
works for the classes that implements 'Comparable' interface otherwise it will throw aNullPointerException
.String
classes implements Comparable interface whileStringBuffer
does not hence you can use"foo".compareTo("doo")
inString
object but not inStringBuffer
Object.Equals can be more efficient then compareTo.
If the length of the character sequences in String doesn't match there is no way the Strings are equal so rejection can be much faster.
Moreover if it is same object (identity equality rather then logical equality), it will also be more efficient.
If they also implemented hashCode caching it could be even faster to reject non-equals in case their hashCode's doesn't match.
The 2 main differences are that:
equals
will take any Object as a parameter, butcompareTo
will only take Strings.equals
only tells you whether they're equal or not, butcompareTo
gives information on how the Strings compare lexicographically.I took a look at the String class code, and the algorithm within compareTo and equals looks basically the same. I believe his opinion was just a matter of taste, and I agree with you -- if all you need to know is the equality of the Strings and not which one comes first lexicographically, then I would use
equals
.