What is the Comparable interface in Kotlin, and what does implementing compareTo give you?
answer
- compareTo returns negative / zero / positive by sign
- operator fun -> enables < > <= >= and ..
- Natural order = one default order baked into the type
- Use compareValuesBy to avoid overflow-prone subtraction
- Comparable = built-in, Comparator = external
basics
~10 sComparable means a type has a built-in natural order. You write compareTo, which returns a negative number, zero, or positive number. Then you can sort the items and use < and > on them.
solid answer
~40 sComparable<T> is the standard library interface that defines a type's natural ordering via a single method, compareTo(other: T): Int. It must return a negative Int when this is less than other, 0 when equal in order, and positive when greater. Implementing it unlocks Kotlin's comparison operators (<, >, <=, >=) and the range operator (..), because the compiler desugars a < b to a.compareTo(b) < 0. It also lets you call sorted(), sortedDescending(), min(), max(), and use the value in a sorted collection like TreeSet or a sorted map. Many built-in types (Int, String, BigDecimal, LocalDate) already implement Comparable, so they sort and compare out of the box.
code
kotlin · 8 linesdata class Money(val cents: Long) : Comparable<Money> {
override fun compareTo(other: Money): Int = cents.compareTo(other.cents)
}
val prices = listOf(Money(500), Money(150), Money(999))
println(prices.sorted()) // ascending by cents
println(prices.max()) // Money(999)
println(Money(150) < Money(500)) // truego deeper
Knows Comparable means natural order and compareTo returns negative/zero/positive enabling sorting and < >.
Explains the operator desugaring (a < b -> a.compareTo(b) < 0) and uses compareValuesBy instead of unsafe subtraction.
Discusses the compareTo/equals consistency contract and its impact on TreeSet/TreeMap membership.
Frames natural order as an API design choice: when a type should expose one canonical order vs leaving ordering to callers via Comparator.
## What Comparable is `Comparable<T>` is a Kotlin standard-library interface with exactly one method: ```kotlin public interface Comparable<in T> { public operator fun compareTo(other: T): Int } ``` Implementing it declares that your type has a **natural ordering** — a single, default way to rank instances. ## The compareTo contract `compareTo` returns an `Int` interpreted by **sign**, not magnitude: - **negative** -> `this` comes before `other` (this < other) - **zero** -> they are equal in ordering - **positive** -> `this` comes after `other` (this > other) The contract requires it to be: *consistent* (a < b implies b > a), *transitive* (a < b and b < c implies a < c), and ideally *consistent with equals* (compareTo == 0 should agree with `equals`). Returning `0` while `equals` says unequal is legal but causes surprises in `TreeSet`/`TreeMap`, which use compareTo, not equals, to decide membership. ## What you unlock Because `compareTo` is marked `operator`, the compiler rewrites comparison operators: - `a < b` becomes `a.compareTo(b) < 0` - `a >= b` becomes `a.compareTo(b) >= 0` - the range operator `a..b` and `in` checks on ranges also use it You also get `sorted()`, `sortedDescending()`, `min()`, `max()`, `coerceIn`, and sorted containers like `sortedSetOf` / `TreeSet`. ## Example ```kotlin data class Version(val major: Int, val minor: Int) : Comparable<Version> { override fun compareTo(other: Version): Int = compareValuesBy(this, other, { it.major }, { it.minor }) } val a = Version(1, 2) val b = Version(1, 5) println(a < b) // true -> a.compareTo(b) < 0 println(listOf(b, a).sorted()) // [Version(1,2), Version(1,5)] ``` `compareValuesBy` is a stdlib helper that compares by each selector in turn — a clean way to avoid hand-rolled subtraction (which can overflow for raw Int math). ## Comparable vs Comparator `Comparable` is the *one* natural order baked into the type. A `Comparator` is an *external*, swappable ordering you supply at the call site (e.g. `sortedWith(comparator)`). Use Comparable for the obvious default; use Comparator when you need alternative orderings.
- Why prefer cents.compareTo(other.cents) over returning (cents - other.cents).toInt()?Subtraction can overflow Int/Long for far-apart values, giving the wrong sign. compareTo (or compareValuesBy) is overflow-safe.
- Does implementing Comparable affect equals/hashCode?No, they are independent. But for TreeSet/TreeMap, compareTo (not equals) decides equality, so keep them consistent to avoid surprises.
Comparable is like the height marked on each person; once everyone has it, you can line them up shortest to tallest automatically.
saying these in an interview costs you the question
- Saying compareTo returns true/false instead of an Int
- Returning a - b and ignoring integer overflow
- Claiming the magnitude (not the sign) of the result matters
- Confusing Comparable (one natural order) with Comparator (external order)
- Thinking you must override < and > directly instead of compareTo