Finamore00
Finamore00

Reputation: 45

Why is my Kotlin comparable not makign correct equality comparisons?

I am currently trying to make a comparable object and working on the compareTo() function, for which I wrote the following code

    class InfoAcad(e: String, m: String, c: Int): Comparable<InfoAcad> {
          override operator fun compareTo(other: InfoAcad): Int {
                if (this.e < other.e) return -1
                if (this.e > other.e) return 1
                if (this.e == other.e && this.m < other.m) return -1
                if (this.e == other.e && this.m > other.m) return 1
                return 0
         }
    }

The idea is that e is an ID number inputted as a string, which always follows the format XX-XXX where every X character is an integer between 0 and 9, and m is a course code following the format LL-XXX where each L character is a capital letter between A and Z and the X characters are integers between 0 and 9 like in the ID numbers. The objects are first compared by their ID number, and if the ID numbers are equal they are then compared by the course code, if both values are the same then the objects are equal, the c parameter is not taken into account in the comparison. I found out yesterday that I could compare strings directly in Kotlin in < and > relations, so I decided to try using that to make the task of comparing the InfoAcad objects a bit easier on myself, however when I make a main function to test the comparisons, the equality always returns a false value independently of what is in the string values of the InfoAcad objects. Here's said main function:

    fun main() {
         var A = InfoAcad("18-10125", "CI-2526", 3)
         var B = InfoAcad("18-10125", "CI-2526", 5)
         println("A = B: " + (A == B).toString()) //true
         println("A < B: " + (A < B).toString())  //false  
         ptintln("A > B: " + (A > B).toString())  //false
   }

When I change characters in the ID and course code values the inequality relations work just as intended, so what could be causing the equality relation to always return false? I appreciate and thank any responses in advance.

Note: I have also tried giving A and B the same c value, the equality part still returned false.

Upvotes: 2

Views: 1438

Answers (2)

mightyWOZ
mightyWOZ

Reputation: 8315

Because == and != translates to a call to equals(other: Any?): Boolean method, from kotlinlang

Expression                 Translated to

a == b                     a?.equals(b)   ?: (b === null)
a != b                     !(a?.equals(b) ?: (b === null))

These operators only work with the function equals(other: Any?): Boolean, which can be overridden to provide custom equality check implementation. Any other function with the same name (like equals(other: Foo)) will not be called.

Upvotes: 1

Sam
Sam

Reputation: 9944

Override the equals function as well, or use a data class.

compareTo is only used for the < and > operators. The == operator is implemented by the separate equals function.

You can find the available operators, and the functions you need to override for each, in the Operator overloading section of the Kotlin docs.

If you don't override the equals function, the default behaviour is for it to use object identity. That means that two different objects, even if they contain the same fields, will never be considered equal.

There is however a nice shortcut for what you want to do! Kotlin will automatically generate an equals function for you if you make your class a data class. It's a good fit for classes like yours, whose main purpose is to hold data.

Upvotes: 3

Related Questions