Выражения объектов Kotlin: пример компаратора


Этот код в основном сортирует массив в порядке убывания:

val arrayList = arrayListOf(1, 5, 2)

Collections.sort(arrayList, object : Comparator<Int> {
   override fun compare(x : Int, y: Int) = y - x
})

Как в мире работает переопределение метода сравнения с y - x? Откуда Котлин знает, что y - x означает поставить y Перед x, Если y < x?

3 10

3 ответа:

На самом деле это не имеет никакого отношения к Котлину. Это связано с интерфейс Comparator интерфейс Java API-интерфейс, и как сборники.сортировка использует его.

Из документации:

Сравнивает свои два аргумента для порядка. Возвращает отрицательное целое число, ноль, или положительное целое число, так как первый аргумент меньше, равен до, или больше, чем второй.

Теперь давайте попробуем это для аргументов, которые вы дали:

  • 1 - 5 = -4 (отрицательное целое число), таким образом, 1 меньше, чем 5.
  • 5 - 2 = 3 (положительное целое число), поэтому 5 больше 2.
  • и т. д...

Collections.sort ничего не знает о том, что означает y - x. Он просто соблюдает определенный контракт интерфейса компаратора, который также должен соблюдать любой исполнитель (если он хочет работать).

Так уж получилось, что y - x - это реализация, которая действительно соблюдает этот контракт, потому что математика.

Поскольку Comparator является интерфейсом SAM, вы можете написать этот код более лаконично, используя лямбду:

Collections.sort(arrayList, {x : Int, y: Int -> y - x})

Или даже

Collections.sort(arrayList) {
    x, y -> y - x
}
Так как лямбда является последним параметром функции sort, то можно вывести тип данных x и y.
Взятие двух объектов и определение для них одного целого числа является абстракцией определения рода. Вы в основном указываете, в каком порядке будут располагаться эти элементы, если их отсортировать.

Для сортировки целых чисел это может показаться излишним, но подумайте о необходимости сортировки более сложных объектов, например экземпляров класса Car.

Этот класс имеет colorCode, и вы хотите отсортировать по этому:

Collections.sort(cars) {
    car1, car2 -> car1.colorCode - car2.colorCode
}

Именно так можно было бы абстрактно определить порядок для этих объектов.

В Kotlin вы также можете сортировать элементы с помощью функций расширения коллекций kotlin sort, sorted, sortBy .... etc

val arrayList = arrayListOf(1, 5, 2).sorted() //1,2,5

Или

val arrayList = arrayListOf(1, 5, 2).sortedDescending() //5,2,1