0Pricing
Kotlin Academy · Урок

Операторы сравнения

compareTo и equals

«Операторы сравнения» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Сравнение пользовательских типов

Чтобы использовать <, >, <=, >= для своего типа, определите operator fun compareTo, возвращающую значение типа Int.

data class Money(val cents: Int) {
    operator fun compareTo(o: Money) = cents - o.cents
}

fun main() {
    println(Money(500) > Money(200))
}

Контракт compareTo

compareTo возвращает отрицательное число, если получатель меньше, ноль — если значения равны, и положительное число — если получатель больше.

data class Version(val n: Int) {
    operator fun compareTo(o: Version) = n - o.n
}

fun main() {
    println(Version(2).compareTo(Version(5)))
}

Реализация Comparable

Реализация интерфейса Comparable<T> — идиоматичный подход; его compareTo уже является оператором.

data class Score(val value: Int) : Comparable<Score> {
    override fun compareTo(other: Score) = value - other.value
}

fun main() {
    println(Score(10) < Score(20))
}

Сортировка с помощью Comparable

После того как тип станет Comparable, функции коллекций, такие как sorted(), будут работать автоматически.

data class Player(val rank: Int) : Comparable<Player> {
    override fun compareTo(other: Player) = rank - other.rank
}

fun main() {
    val sorted = listOf(Player(3), Player(1), Player(2)).sorted()
    println(sorted.map { it.rank })
}

Использование compareValuesBy

Для сравнений по нескольким полям compareValuesBy сравнивает значения по каждому селектору в заданном порядке.

data class Person(val age: Int, val name: String) : Comparable<Person> {
    override fun compareTo(other: Person) =
        compareValuesBy(this, other, { it.age }, { it.name })
}

fun main() {
    println(Person(30, "Al") < Person(30, "Bo"))
}

Равенство с помощью equals

Оператор == вызывает equals, а не compareTo. Переопределите equals, чтобы управлять равенством значений.

class Id(val value: Int) {
    override fun equals(other: Any?) =
        other is Id && other.value == value
    override fun hashCode() = value
}

fun main() {
    println(Id(7) == Id(7))
}

equals и hashCode вместе

Если Вы переопределяете equals, необходимо также переопределить hashCode, чтобы равные объекты имели одинаковое хеш-значение и хеш-коллекции работали корректно.

class Tag(val name: String) {
    override fun equals(other: Any?) = other is Tag && other.name == name
    override fun hashCode() = name.hashCode()
}

fun main() {
    val set = hashSetOf(Tag("a"), Tag("a"))
    println(set.size)
}

Data-классы делают это за Вас

data class автоматически создаёт equals и hashCode на основе своих свойств, поэтому == сравнивает значения.

data class Coord(val x: Int, val y: Int)

fun main() {
    println(Coord(1, 2) == Coord(1, 2))
}

Равенство и идентичность

== вызывает equals и проверяет равенство значений, а === проверяет идентичность ссылок. Результаты могут различаться.

data class Box(val n: Int)

fun main() {
    val a = Box(1)
    val b = Box(1)
    println(a == b)
    println(a === b)
}

Сравнение в условиях

Если определить compareTo, Ваш тип можно использовать в if и when так же, как числа.

data class Weight(val g: Int) : Comparable<Weight> {
    override fun compareTo(other: Weight) = g - other.g
}

fun main() {
    val w = Weight(50)
    println(if (w > Weight(40)) "heavy" else "light")
}

maxOf и minOf

Типы, реализующие Comparable, работают с maxOf и minOf.

data class T(val v: Int) : Comparable<T> {
    override fun compareTo(other: T) = v - other.v
}

fun main() {
    println(maxOf(T(3), T(8)).v)
}

Быстрая проверка

Проверьте, насколько хорошо Вы поняли операторы сравнения.

Итоги

Вы узнали об операторах сравнения:

  • compareTo реализует <, >, <=, >= и возвращает отрицательное, нулевое или положительное значение.
  • Реализуйте Comparable<T> для идиоматичной сортировки и упорядочивания.
  • == использует equals; всегда переопределяйте его вместе с hashCode.
  • Data-классы автоматически создают equals и hashCode.
data class S(val v: Int) : Comparable<S> {
    override fun compareTo(other: S) = v - other.v
}

fun main() {
    println(S(2) < S(5))
}

Часто задаваемые вопросы

Урок «Операторы сравнения» бесплатный?

Да — полный текст урока «Операторы сравнения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «Операторы сравнения»?

compareTo и equals Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Операторы сравнения»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Функции-операторы
  2. Операторы сравнения
  3. Индексация и вызов
  4. Лучшие практики
← Назад к Kotlin Academy