0

Lets say I have class A(val foo: Double).

I want to be be able to compare it to other A, Double, and Int.

If I implement Comparable, I can only compare it against one other object type.

override fun compareTo(other: A): Int {
        return when {
            this.foo == other.foo -> 0
            this.foo > other.foo -> 1
            else -> -1
        }
    }

But I've also seen extension functions overriding the compareTo operator.

operator fun A.compareTo(d: Double): Int {
    return when {
        this.foo == d -> 0
        this.foo > d -> 1
        else -> -1
    }
}

What is the difference between these and what should I be using? I'm guessing if I want to compare it to multiple types then I have to use extension functions?

  • 1
    [`Comparable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-comparable/) is just an interface that enforces implementation of said operator function – Pawel Dec 17 '20 at 22:06

3 Answers3

1

The Comparable interface comes from Java, and, as you have seen, is defined with only a compareTo( other) method, which only provides for comparing an object to another object of the same type.

As you have also noticed, the Kotlin extension functions are additional functions allowing you to compare an object to whatever you want, as long as you define the compareTo method to take an argument of the type to which you want to compare.

So, yes, if you want to compare an object to an object of a different type, you will need to write an appropriate extension function.

Of course, in Java, if you have control of the source code of the class, you can always add a custom compareTo method.

GreyBeardedGeek
  • 29,460
  • 2
  • 47
  • 67
0

Wenn you make your own objects you must implement Comparable interface and then override compareTo function

class MyClass : Comparable<MyClass> {

   override fun compareTo(other: MyClass): Int {
      // TODO Returns zero if this object is equal to the specified other object
   }

}

You can also override an operator function, for example from Int class in kotlin

fun main(args: Array<String>) {
   val a = 1
   val b = "2"
   println(a.compareTo(b))
}

operator fun Int.compareTo(i: String) : Int {
   return if (this.toString() == i) {
      0
   } else {
      1
   }
}

I hope that's helpfull from you

  • Of course, you can just use an extension function to make your own compareTo() function from your objects and don't implement Comparable interface! – Ioannis Tzavaras Dec 17 '20 at 23:02
0

Comparable is a standard interface, it's the way you define a class as having some ordering, and every library that deals with ordering works with Comparable types. Basically, if you want to be able to order and compare your things using all the standard functions and anything anyone else might write, you need to implement the Comparable interface.

This works:

data class SportsTeam(val name: String) : Comparable<SportsTeam> {
    override fun compareTo(other: SportsTeam): Int = when {
        name == "best team" -> 1
        other.name == "best team" -> -1
        else -> 0
    }
}

fun main(args: Array<String>) {
    val best = SportsTeam("best team")
    val worst = SportsTeam("worst team")
    print("The winner is: ${maxOf(best, worst).name}")
}

but because maxOf takes a Comparable type, this won't work:

data class SportsTeam(val name: String)

fun SportsTeam.compareTo(other: SportsTeam): Int = when {
    name == "best team" -> 1
    other.name == "best team" -> -1
    else -> 0
}

fun main(args: Array<String>) {
    val best = SportsTeam("best team")
    val worst = SportsTeam("worst team")
    print("The winner is: ${maxOf(best, worst).name}")
}
cactustictacs
  • 17,935
  • 2
  • 14
  • 25