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?
equals() checks whether two strings are equal or not.It gives boolean value. compareTo() checks whether string object is equal to,greater or smaller to the other string object.It gives result as : 1 if string object is greater 0 if both are equal -1 if string is smaller than other string
eq:
equals
can take any Object as a parameter butcompareTo
can only take String.when cometo null,
compareTo
will throw a exceptionwhen you want to know where the diff happen,you can use
compareTo
.equals
: required for checking equality and restricting duplicates. Many classes of Java Library use this in case they wanted to find duplicates. e.g.HashSet.add(ob1)
will only add if that doesn't exist. So if you are extending some classes like this then overrideequals()
.compareTo
: required for ordering of element. Again for stable sorting you require equality, so there is a return 0.In String Context:
compareTo: Compares two strings lexicographically.
equals: Compares this string to the specified object.
compareTo compares two strings by their characters (at same index) and returns an integer (positive or negative) accordingly.
String.equals()
requires invokinginstanceof
operator whilecompareTo()
requires not. My colleague has noted large performance drop-down caused by excessive numbers ofinstanceof
calls inequals()
method, however my test has provedcompareTo()
to be only slightly faster.I was using, however, Java 1.6. On other versions (or other JDK vendors) the difference could be larger.
The test compared each-to-each string in 1000 element arrays, repeated 10 times.
This is an experiment in necromancy :-)
Most answers compare performance and API differences. They miss the fundamental point that the two operations simply have different semantics.
Your intuition is correct. x.equals(y) is not interchangeable with x.compareTo(y) == 0. The first compares identity, while the other compares the notion of 'size'. It is true that in many cases, especially with primitive types, these two co-align.
The general case is this:
If x and y are identical, they share the same 'size': if x.equals(y) is true => x.compareTo(y) is 0.
However, if x and y share the same size, it does not mean they are identical.
if x.compareTo(y) is 0 does not necessarily mean x.equals(y) is true.
A compelling example where identity differs from size would be complex numbers. Assume that the comparison is done by their absolute value. So given two complex numbers: Z1 = a1 + b1*i and Z2 = a2 + b2*i:
Z1.equals(z2) returns true if and only if a1 = a2 and b1 = b2.
However Z1.compareTo(Z2) returns 0 for and infinite number of (a1,b1) and (a2,b2) pairs as long as they satisfy the condition a1^2 + b1^2 == a2^2 + b2^2.