Compareto() VS. Equals()

compareTo() vs. equals()

A difference is that "foo".equals((String)null) returns false while "foo".compareTo((String)null) == 0 throws a NullPointerException. So they are not always interchangeable even for Strings.

CompareTo versus Equals! compares strings or objects?

First of all == compares the references to see if the two objects are the same (so == is on the object).

Then String.equals() verify the equality of the content of two strings while String.compareTo() seek the difference of the content of two strings.

So the two following tests are equivalent:

String str = "my string";

if ( str.equals("my second string")) {/*...*/}
if ( str.compareTo("my second string")==0) {/*...*/}

But, since String.equals is making a reference check first, it's safe when used against null, while String.compareTo will throws a NullPointerException:

String str = "my string";

if ( str.equals(null)) {/* false */}
if ( str.compareTo(null) {/* NullPointerException */}

C#: What is the difference between CompareTo(String) and Equals(String)?

From MSDN:

string.CompareTo:

Compares this instance with a specified object or String and returns
an integer that indicates whether this instance precedes, follows, or
appears in the same position in the sort order as the specified object
or String.

string.Equals:

Determines whether two String objects have the same value.

In short, CompareTo is used for sorting. Equals is used to determine equality.

String comparision with equals and compareTo - which is faster?

Note a very important difference between compareTo and equals:

"myString".compareTo(null);  //Throws java.lang.NullPointerException
"myString".equals(null); //Returns false

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.

Also note that equals makes a == first! This might be a big advantage when the objects are identical. Specially when you mentioned that you have a huge amount of Strings, because Java interns Strings, this might happen more than you thought.


Although you asked about Strings, but I want to add this note:

These methods can be very different when BigDecimal is involved. For example, see the docs:

equals compares this BigDecimal with the specified Object for equality.
Unlike compareTo, this method considers two BigDecimal objects equal
only if they are equal in value and scale (thus 2.0 is not equal to
2.00 when compared by this method).

What is the difference between compareTo and equals in Kotlin?

The difference between equals and compareTo comes from a few sources.

First, equals is inherited from the Any type in Kotlin, so it is a method attached to all values in the language.

compareTo is inherited from the Comparable type, specifically meaning only its inheritors of:

Boolean, Byte, Char, Double, Duration, Enum, Float, Int etc...
will have the method.


Second, the signature of returned value is different.
Equals has a return of Boolean, meaning you only have true or false being returned from the method call. This will only tell you directly if they are the same or not, with no extra information

The compareTo method has a return of Int, which is a magnitude of the difference between the comparison of the input type. The comparison can not be between different types.

The return of a positive Integer that the Receiver value, is greater than the input value being checked against
To clarify, the Receiver is the variable or instance that the compareTo method is being called on.
For example:

val myValue: Boolean = false
val myCheck: Boolean = true

myValue.compareTo(myCheck) // Return: 1

In that code, the Receiver would be myValue because it is calling the method compareTo. Kotlin interprets true to be a greater value than false so myValue.compareTo(myCheck) will return1`

The return of 0 means that the Receiver value is the same value as the input parameter value.

val myValue: Boolean = true
val otherValue: Boolean = true
myValue.compareTo(otherValue) // Return: 0

The return of a negative number is a magnitude of difference between the two values, specific to each type based on the Receiver value being considered a value of less than the input parameter.

val myString = "zza"
val otherString = "zzz"

myString.compareTo(otherString) // Return: -25

The equality being a bit complicated to explain, but being the same length with only 1 Char place being different, it returns the difference of the Char values as an Int.

val myString = "zz"
val otherString = "zzz"

myString.compareTo(otherString) // Return: -1

In this case the difference is literally the existence of 1 Char, and does not have a value difference to assign.


For equals, the comparative other can be of Any type, not specifically the same type as the Receiver like in compareTo.
The equals method is also an operator function and can be syntactically used such as:

val myString: String = "Hello World"
val otherString: String = "Hello World"

myString == otherString // Return: true

Any non-null value can not be equal to null:

val myString = "Hello World"
val maybeNull: String? = null

myString == maybeNull // Return: false

Equality is specific to each type and has it's own specific documentation to clarify its nuances: Kotlin Equality

Relationship between equals and compareTo methods

  • Your compareTo method compares Fruits based on their size. This is a custom implementation.
  • Collections.max will invoke compareTo a number of times related to the size of your collection, to infer the max item in the collection, hence compareTo is invoked.
  • Object#equals will be invoked when invoking equals in your example, as it is not overridden in Fruit.
  • The equality will be tested between the "largest" fruit in your collection, and the second Apple you declared, i.e. between the same Apple with size 2 in this case. It should return true.

Java Comparable object equals() and compareTo() returning different results

compareTo and equals methods are completely unrelated from the perspective of the JVM. It is programmer's duty to make natural order consistent with equals.

If only compareTo method is provided for the class Employee, the default implementations, derived from Object is inherited. You should override equals method (together with hasCode) to get consistent results.

Why it is implied that objects are equal if compareTo() returns 0?

Extract from the java.util.SortedSet javadoc:

Note that the ordering maintained by a sorted set (whether or not
an explicit comparator is provided) must be consistent with equals if
the sorted set is to correctly implement the Set interface. (See the
Comparable interface or Comparator interface for a precise definition
of consistent with equals.) This is so because the Set interface is
defined in terms of the equals operation, but a sorted set performs
all element comparisons using its compareTo (or compare) method, so
two elements that are deemed equal by this method are, from the
standpoint of the sorted set, equal. The behavior of a sorted set is
well-defined even if its ordering is inconsistent with equals; it just
fails to obey the general contract of the Set interface.

Hence, in other words, SortedSet breaks (or "extends") the general contracts for Object.equals() and Comparable.compareTo. See the contract for compareTo:

It is strongly recommended, but not strictly required that
(x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class
that implements the Comparable interface and violates this condition
should clearly indicate this fact. The recommended language is "Note:
this class has a natural ordering that is inconsistent with equals."

Difference between equals and compareto method in java string

According to the documentation of compareTo()

[...] If two strings are different, then
either they have different characters
at some index that is a valid index
for both strings, or their lengths are
different, or both. If they have
different characters at one or more
index positions, let k be the smallest
such index; then the string whose
character at position k has the
smaller value, as determined by using
the < operator, lexicographically
precedes the other string. In this
case, compareTo returns the difference
of the two character values at
position k in the two string -- that
is, the value:

 this.charAt(k)-anotherString.charAt(k)

If there is no index position at which
they differ, then the shorter string
lexicographically precedes the longer
string. In this case, compareTo
returns the difference of the lengths
of the strings -- that is, the value:

 this.length()-anotherString.length()

Hence, 22 is not the position of the differing character in the two strings, but the distance between the first dissimilar characters.

As for your second question, I believe a simple iteration through the characters in both strings will allow you to pinpoint easily the first character position where they differ



Related Topics



Leave a reply



Submit