В чем разница между Comparable и Comparator?
Получается, это дублирующие друг друга вещи. Может, есть какие-то реальные различия?
Отслеживать
4,286 14 14 золотых знаков 42 42 серебряных знака 92 92 бронзовых знака
задан 14 мар 2017 в 0:41
5,297 11 11 золотых знаков 58 58 серебряных знаков 116 116 бронзовых знаков
Простыми словами — Comparable — сравниваемое, Comparator — сравнитель (то, что делает сравнение)
14 мар 2017 в 6:41
4 ответа 4
Сортировка: Сброс на вариант по умолчанию
- Comparator и Comparable — это оба интерфейсы
- Коллекция (ну хорошо, объект) является Comparable , когда объект может быть как то сравнен с другим объектом.
- Comparator , в отличие от этого — это способ сравнения объектов.
Пример: школьники на уроке физкультуры, физрук говорит: строиться по росту! — ученики быстренько сравнивают свои росты и строятся — кто выше вперед, кто ниже в хвост строя — это пример реализации Comparable , где в качестве compareTo(сосед) используется рост учеников.
Второй пример: те же школьники. Директор дает задание учителю математики сравнить учеников по успеваемости. Математичка берет журнал и сравнивает учеников по успеваемости — здесь работает compare(ученик1, ученик2) — Comparator’ом выступает математичка. Аналогично компаратором может выступить русичка или трудовик.
Отслеживать
33.9k 25 25 золотых знаков 130 130 серебряных знаков 222 222 бронзовых знака
Java : Comparable vs Comparator [duplicate]
What are the keys differences between Comparable and Comparator. and which is preferred over the other in what scenarios? Thanks Updated — GOOD LINK WITH EXAMPLE!! http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html
1 1 1 silver badge
asked Nov 5, 2010 at 17:51
daydreamer daydreamer
88k 194 194 gold badges 453 453 silver badges 729 729 bronze badges
Nov 5, 2010 at 17:52
Also a dup of: When to use Comparable and Comparator.
Jul 6, 2015 at 2:27
Excellent example link. Simple and clear. Do read.
Oct 10, 2016 at 19:45
Your updated link is full of advertisement, and even cannot remove.
Nov 14, 2016 at 18:29
You may look at this smugjava.blogspot.in/2017/11/…
Nov 11, 2017 at 6:32
2 Answers 2
When your class implements Comparable, the compareTo method of the class is defining the «natural» ordering of that object. That method is contractually obligated (though not demanded) to be in line with other methods on that object, such as a 0 should always be returned for objects when the .equals() comparisons return true.
A Comparator is its own definition of how to compare two objects, and can be used to compare objects in a way that might not align with the natural ordering.
For example, Strings are generally compared alphabetically. Thus the «a».compareTo(«b») would use alphabetical comparisons. If you wanted to compare Strings on length, you would need to write a custom comparator.
In short, there isn’t much difference. They are both ends to similar means. In general implement comparable for natural order, (natural order definition is obviously open to interpretation), and write a comparator for other sorting or comparison needs.
Выбор между Comparator и Comparable
Для реализации сортировки требуется, чтобы сортируемые объекты можно было сравнивать между собой на больше-меньше. Иначе говоря, чтобы было определено правило, которое позволит для любых двух объектов указать, какой из них в рамках данного контекста идет раньше, а какой позже.
В java эти правила определяются на уровне классов, к которым принадлежат объекты. Для примера возьмем класс для описания счета пользователя:
UserAccount
В зависимости от контекста сравнение счетов пользователя может происходить по разным правилам, например:
- в приложении пользователь видит счета, отсортированные по currency, потом по value;
- в админке счета всех пользователей отсортированы по дате изменения.
Для реализации сравнения на больше-меньше в java предусмотрено две возможности:
- UserAccount реализует интерфейс Comparable В этом случае два объекта получают возможность сравнения между собой: acc1.compareTo(acc2)
- Создается отдельный класс, реализующий интерфейс Comparator , и дальше объект этого класса может сравнить между собой два объекта исходного класса: 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 < @Override public int compareTo(UserAccount other) < .. >>
Как определить, где используется объявленный метод compareTo ? Если искать по использованию метода, то потребуется включить в поиск и метод суперкласса Comparable#compareTo , так как именно он будет найден в Arrays.sort() . Но метод суперкласса используется также в огромном количестве других мест внутри кода jdk, и найти таким образом его будет сложно. Я не нашел способов искать такие использования методов кроме как ручным перебором: ищем все включения класса UserAccount и ниже по стеку обращаем внимание на все Arrays.sort(), stream.sorted() и тд.
В случае явной передачи компаратора найти его использования элементарно. Я считаю это аргументом за использование компаратора. (Еще одним примером сложностей с поиском неявных использований может служить equals/hashCode, но альтернативы в виде «Equalator»-а для них нет).
Резюмируя — в большинстве случаев аргументы за использование Comparator перевешивают аргументы за использование Comparable.
- java core
- comparator
- comparable
- explicit is better th. oh shut up
Разница между Comparator и Comparable в Java
Один из распространенных вопросов интервью: «В чем различия между Comparator и Comparable». или «Как вы будете сортировать коллекцию объектов сотрудников по их идентификатору или имени». Для этого мы можем использовать два интерфейса. Например, Comparator и Comparable. Прежде чем мы действительно увидим различия, позвольте мне кратко представить оба.
Сопоставимый интерфейс: класс, чьи объекты для сортировки должны реализовывать этот интерфейс. В этом случае мы должны реализовать метод compareTo (Object).
public class Country implements Comparable< public int compareTo(Object arg0) < Country country=(Country) arg0; return ( this .countryId < country.countryId ) ? - 1 : ( this .countryId >country.countryId ) ? 1 : 0 ;
Если какой-либо класс реализует сопоставимый интерфейс, тогда коллекция этого объекта может быть автоматически отсортирована с помощью Collection.sort () или Arrays.sort (). Объект будет отсортирован на основе метода compareTo в этом классе.
Объекты, которые реализуют Comparable в Java, могут использоваться в качестве ключей в SortedMap, таком как TreeMap или SortedSet, как TreeSet, без реализации какого-либо другого интерфейса.
Интерфейс компаратора: класс, чьи объекты для сортировки не должны реализовывать этот интерфейс. Некоторые третьи классы могут реализовывать этот интерфейс для sort.egCountrySortByIdComparator, класс может реализовывать интерфейс Comparator для сортировки коллекции объекта страны по идентификатору. Например:
