Как работает Comparator.compare ()? - PullRequest
0 голосов
/ 01 марта 2019

Изучая Kotlin, я пытаюсь понять, как работает интерфейс Java Comparator - в основном функция compare(), поэтому я могу его использовать.

Я пытался читать документы для compare(), но я хотел бы получить более простое объяснение того, как это работает.

Что такое x и y в compare(x, y) при итерации по списку?Целевая и сравнивает ли каждая пара чисел при итерации?Например:

arrayOf(1, 2, 3, 4)

будет ли сравниваться 1 и 2 (x и y), затем 2 и 3 (x и y), затем 3 и 4 (x и y)?

У меня есть функция Kotlin, которая предоставляет компаратор для сортировки списка в порядке убывания:

import java.util.*

fun getList(): List<Int> {
    val arrayList = arrayListOf(1, 5, 2)
    Collections.sort(arrayList, object: Comparator<Int> {
        override fun compare(x: Int, y: Int){
            return x < y
        }
    } )
    return arrayList

Я не уверен, почему вышеприведенная функция не является правильным синтаксисом для завершениячто.

Ответы [ 4 ]

0 голосов
/ 01 марта 2019

Comparator только интерфейс для классов, которые можно сравнивать.Речь идет о сравнении любых двух объектов.Ни больше ни меньше.Из документов:

@ param o1 первый объект для сравнения.

@ param o2 второй объект для сравнения.

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

Сортировка - это совсем другое.Он использует компаратор (было бы трудно что-либо сортировать, не зная, как сравнивать два элемента), поэтому вы можете предоставить свой собственный способ сортировки коллекции.

Но как это сортировать?Все, что мы знаем о сортировке через Collections.sort(collection, comparator), это то, что сортировка стабильна.Подробнее о сортировке: https://www.geeksforgeeks.org/sorting-algorithms/

0 голосов
/ 01 марта 2019

Это сводится к этому утверждению из javadoc :

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

Это все, что нужно для этого.Когда вы пишете компаратор, вы определяете , какой порядок вы хотите.Ключевым моментом является то, что ваш метод возвращает -1, 0 или 1. В зависимости от того, как вы хотите упорядочить эти два входящих аргумента.(и да, ему не нужно -1 или 1, только отрицательный, ноль, положительный).

Другими словами: ключевой момент заключается в том, что compare() служит в этом контракте.Он определяет порядок на двух элементах.Это все, что нужно для этого.

При сортировке данных они будут вызываться каждый раз, когда базовый код сортировки должен знать порядок двух элементов.Таким образом, точный «порядок», в котором происходят эти вызовы, и какие аргументы передаются, зависит от фактического алгоритма сортировки и данных, которые вы собираетесь сортировать.

С этой точки зрения, ваш вопрос подразумевает, что вынекоторые продумывали всю тему.Просто поймите: вы используете компаратор, когда намереваетесь определить «пользовательский» порядок для ваших объектов / значений.

И нет смысла определять ваш «собственный» компаратор для int, Int или Integer, какэти классы уже определяют их естественный порядок, поэтому уже существует, например, Integer.compare () .Единственный вариант использования для определения собственного компаратора для такого класса - это когда вы хотите упорядочить их по-другому.Но, скорее всего, тогда вы все равно используете существующие функции компаратора и используете другие встроенные способы, например, обратный «естественный» порядок.

0 голосов
/ 01 марта 2019

Документация compare довольно ясна:

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

Таким образом, вы должны возвращать Int из вашей функции, а не логическое значение.

Чтобы предоставить работающий код Котлина, я привожу пример:

val list = listOf(1, 5, 2)
list.sortedWith(Comparator { x, y ->
       x.compareTo(y)
})

Сама сортировка может выполняться с разными алгоритмами, но они будут использовать compareTo внутри.Документация Collections дает представление:

Документация по полиморфным алгоритмам, содержащаяся в этом классе, обычно включает краткое описание реализации.Такие описания следует рассматривать как замечания по реализации, а не как части спецификации.Разработчики должны свободно заменять другие алгоритмы при условии соблюдения самой спецификации.(Например, алгоритм, используемый сортировкой, не обязательно должен быть сортировкой слиянием, но он должен быть стабильным.)

0 голосов
/ 01 марта 2019

A Comparator<T> - это просто способ сравнить любые 2 элемента типа T.

Что такое x и y в сравнении (x, y) при итерации по списку?

При итерации компаратор вообще не вызывается.

При передаче методу Collections.sort() компаратор используется всякий раз, когда базовому алгоритму сортировки требуется сравнить 2 элемента.

Я не уверен, почему вышеприведенная функция не является правильным синтаксисом для завершения этого.

Ваша текущая реализация не удовлетворяет документации .compare() необходимо вернуть отрицательное целое число, 0 или положительное целое число, в зависимости от того, как 2 элемента связаны друг с другом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...