[Java] Выбор между Comparator и Comparable
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Для реализации сортировки требуется, чтобы сортируемые объекты можно было сравнивать между собой на больше-меньше. Иначе говоря, чтобы было определено правило, которое позволит для любых двух объектов указать, какой из них в рамках данного контекста идет раньше, а какой позже.В java эти правила определяются на уровне классов, к которым принадлежат объекты. Для примера возьмем класс для описания счета пользователя:
UserAccount {
currency
value
updatedTimestamp
}
В зависимости от контекста сравнение счетов пользователя может происходить по разным правилам, например:
- в приложении пользователь видит счета, отсортированные по currency, потом по value;
- в админке счета всех пользователей отсортированы по дате изменения.
Для реализации сравнения на больше-меньше в java предусмотрено две возможности:
- UserAccount реализует интерфейс Comparable<UserAccount> В этом случае два объекта получают возможность сравнения между собой: acc1.compareTo(acc2)
- Создается отдельный класс, реализующий интерфейс Comparator<UserAccount>, и дальше объект этого класса может сравнить между собой два объекта исходного класса: userAccountComparator.compare(acc1, acc2)
Очевидно, что в некоторых случаях выбора между Comparable и Comparator нет. Если исходный класс нельзя модифицировать, или если требуются разные правила сравнения, то придется использовать Comparator. В остальных случаях, технически, можно использовать как Comparator, так и Comparable.Согласно документации использование Comparable возможно, если для сравнения используется естественный порядок (class's natural ordering). По ссылке есть представление разработчиков, что такое естественный порядок для стандартных классов (String, Date). Мне не удалось выяснить, что такое естественный порядок в общем случае. Выглядит, что это интуитивное представление разработчика о порядке в данном контексте. При этом даже для стандартных классов порядок может быть не интуитивен (в каком порядке должны идти значения BigDecimal с разной точностью, например 4.0 и 4.00?). Практика показывает, что "естественность" правил различается в понимании разных разработчиков и контекстов. Для меня необходимость опоры на интуицию является аргументом против использования Comparable.При написании кода приходится лавировать между явностью и неявностью. Явность хороша тем, что для понимания участка кода требуется рассмотреть лишь узкий контекст его использования. В то же время неявность позволяет использовать одинаковые правила для всех участков кода. Разберем на примере: разработчику требуется отсортировать список счетов. Правила сравнения можно указать:
- неявно: Arrays.sort(accountsList)
- явно: Arrays.sort(accountsList, accountByValueComparator)
Чтобы разработчику узнать правила сортировки в первом случае ему нужно будет посмотреть, как реализован метод compareTo у класса UserAccount, а во втором - у accountByValueComparator. Здесь разницы нет. Но посмотрим на обратную задачу. Пусть разработчик видит перед собой код
UserAccount implements Comparable<UserAccount> {
@Override
public int compareTo(UserAccount other) { .. }
}
Как определить, где используется объявленный метод compareTo ? Если искать по использованию метода, то потребуется включить в поиск и метод суперкласса Comparable#compareTo, так как именно он будет найден в Arrays.sort(). Но метод суперкласса используется также в огромном количестве других мест внутри кода jdk, и найти таким образом его будет сложно. Я не нашел способов искать такие использования методов кроме как ручным перебором: ищем все включения класса UserAccount и ниже по стеку обращаем внимание на все Arrays.sort(), stream.sorted() и тд.В случае явной передачи компаратора найти его использования элементарно. Я считаю это аргументом за использование компаратора. (Еще одним примером сложностей с поиском неявных использований может служить equals/hashCode, но альтернативы в виде "Equalator"-а для них нет).Резюмируя - в большинстве случаев аргументы за использование Comparator перевешивают аргументы за использование Comparable.
===========
Источник:
habr.com
===========
Похожие новости:
- [JavaScript, NoSQL, Node.JS] Инструменты Node.js разработчика. Какие ODM нам нужны
- [CSS, JavaScript, Интерфейсы, HTML] Динамическое меню c поддержкой touch move и mouse move на RevolveR
- [Разработка веб-сайтов, JavaScript, ReactJS] Как эффективно применять React Context (перевод)
- [Программирование, Учебный процесс в IT, Карьера в IT-индустрии, Конференции] Бесплатные онлайн-мероприятия по разработке (20 октября — 29 октября)
- [Java] Валидация и обработка исключений с помощью Spring (перевод)
- [Java] Написание более читаемого кода с помощью Project Lombok (перевод)
- [Java, Тестирование IT-систем, Тестирование веб-сервисов] Пожалуй, лучшая архитектура для UI тестов
- [Java, Разработка мобильных приложений, Разработка под Android, Kotlin, Gradle] Встраиваем карты от Huawei в Android приложение
- [Java, Управление персоналом, Софт] How To Build a Password Management Software Using JAVA?
- [Java, Big Data] Distributed File Systems
Теги для поиска: #_java, #_java_core, #_comparator, #_comparable, #_explicit_is_better_th..._oh_shut_up, #_java
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 20:12
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Для реализации сортировки требуется, чтобы сортируемые объекты можно было сравнивать между собой на больше-меньше. Иначе говоря, чтобы было определено правило, которое позволит для любых двух объектов указать, какой из них в рамках данного контекста идет раньше, а какой позже.В java эти правила определяются на уровне классов, к которым принадлежат объекты. Для примера возьмем класс для описания счета пользователя: UserAccount {
currency value updatedTimestamp }
UserAccount implements Comparable<UserAccount> {
@Override public int compareTo(UserAccount other) { .. } } =========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 20:12
Часовой пояс: UTC + 5