Search code examples
kotlin

What is the difference between compareTo and equals in Kotlin?


I want to fully understand the different between compareTo and equals.

I have used this code while trying to understand the difference between them:

println("${'A'.compareTo('b')}")
println("${'A'.equals('b')}")

While using compareTo I get -1 as a result. Nothing is wrong here. It is also mentioned in the documentation that I will get -1 as a result if the strings are not the same:

Compares this object with the specified object for order. Returns zero if this object is equal to the specified other object, a negative number if it's less than other, or a positive number if it's greater than other.

And while using equals the result that I got was false, then again it looks good as the documentation mentioned - this method will return a boolean:

Indicates whether some other object is "equal to" this one.

Maybe I am missing something really simple, but in the described case, what is the difference between those methods (other than the value that is coming from compareTo and equals)?


Solution

  • 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