Когда класс должен быть Comparable и / или Comparator?

Я видел классы, которые реализуют как Comparable, так и Comparator. Что это значит? Почему я должен использовать одно вместо другого?


person Nick Heiner    schedule 17.09.2009    source источник
comment
Вы читали о них javadoc? Он довольно ясно описывает различное.   -  person skaffman    schedule 17.09.2009
comment
Что такое сопоставимый и компаратор, и когда использовать сопоставимый и компаратор. Чтобы узнать об этом, прочтите эту ссылку. это поможет вам понять их поведение и использование. http://iandjava.blogspot.in/2012/10/comparable-and-comparator.html   -  person RockStar    schedule 26.10.2012
comment
Это хороший вопрос с хорошим объективным ответом. Я встревожен тем, что он закрыт.   -  person Russell Silva    schedule 23.07.2013
comment
Другие вопросы по StackOverflow называют это окончательным. В чем разница между компаратором и сопоставимым вопросом. Почему он отмечен как неконструктивный? Как новичок в Java, это был очень полезный вопрос!   -  person Pete    schedule 28.09.2014
comment
comment
Сопоставимо для естественной сортировки / сортировки по умолчанию. И компаратор для индивидуальной сортировки   -  person rahulnikhare    schedule 23.01.2018
comment
Я так думаю об этом. Comparable предоставляет классу способ по умолчанию для сравнения двух собственных объектов. Компаратор предоставляет настраиваемые способы сравнения двух объектов одного типа. У гостиницы есть клиенты. Клиент, который тратит больше денег, важнее. Специальные предложения предназначены только для 10% лучших клиентов. Но иногда мы хотим побудить клиентов с самыми низкими расходами тратить больше. Затем мы можем сравнить по меньшим затратам, получить 5% самых бедных пользователей и также отправлять им специальные предложения.   -  person MasterJoe    schedule 09.04.2020


Ответы (11)


Текст ниже взят из Comparator vs Comparable.

Сопоставимо

Сравнимый объект может сравнивать себя с другим объектом. Сам класс должен реализовывать интерфейс java.lang.Comparable, чтобы иметь возможность сравнивать его экземпляры.

Компаратор

Объект компаратора может сравнивать два разных объекта. Класс сравнивает не свои экземпляры, а экземпляры некоторых других классов. Этот класс компаратора должен реализовывать интерфейс java.util.Comparator.

person Dan    schedule 17.09.2009
comment
для подробного объяснения использования как Comparator, так и сопоставимых: sysdotoutdotprint .com / index.php / 2017/03/28 / - person mel3kings; 28.03.2017
comment
Еще одна хорошая статья: https://web.archive.org/web/20180707182116/http://codecramp.com/java-comparable-vs-comparator/ - person EMM; 09.08.2017

Реализация Comparable означает «Я могу сравнить себя с другим объектом». Обычно это полезно, когда есть одно естественное сравнение по умолчанию.

Реализация Comparator означает «Я могу сравнить два других объекта». Обычно это полезно, когда есть несколько способов сравнения двух экземпляров типа, например вы можете сравнивать людей по возрасту, имени и т. д.

person Jon Skeet    schedule 17.09.2009
comment
Привет, скит, не могли бы вы сбросить код, используя сопоставимый и компаратор. - person Mdhar9e; 15.05.2012
comment
@ mdhar9e: Примеров много - если вам сложно перевести их в свой конкретный сценарий, дайте больше информации в новом вопросе. - person Jon Skeet; 15.05.2012
comment
@JonSkeet Не могли бы вы привести пример того, что сценарий, реализованный Comparator, не может быть легко реализован Comparable? Я не вижу большой разницы между ними - person Alireza Farahani; 30.06.2014
comment
@alireza: Я уже приводил пример во втором абзаце: имея разные компараторы, вы можете отсортировать одну и ту же коллекцию (людей) по разным свойствам (возраст, имя и т. д.). Вы не можете сделать это, просто заставив Person реализовать Comparable, потому что вы не можете затем изменить способ сравнения двух людей. - person Jon Skeet; 30.06.2014
comment
@Jon Skeet Большое спасибо за ваше объяснение. Не могли бы вы привести какой-нибудь пример в реальном времени? - person Nagappa L M; 11.08.2014
comment
@jon Skeet Логика сортировки находится в отдельном классе. Следовательно, мы можем написать различную сортировку на основе разных атрибутов сортируемых объектов. Означает ли это применение разных методов сортировки, таких как пузырьковая, быстрая сортировка и т. Д.? - person Nagappa L M; 11.08.2014
comment
@feelgoodandprogramming: Нет, это разные алгоритмы сортировки. Здесь потенциально есть три фрагмента кода в трех разных классах: 1) Сама сущность, например. Person. 2) Компаратор, например PersonAgeComparator, который может сравнивать две разные сущности и решать, какая из них должна быть первой в этом конкретном порядке сортировки. 3) Код сортировки, который принимает набор сущностей и компаратор и сортирует эту коллекцию, используя компаратор для определения порядка. - person Jon Skeet; 11.08.2014
comment
@JonSkeet, дайте мне знать, что я правильно понимаю. 1) используйте Comparable, если я хочу сравнить только по любому из них, возрасту или имени. И 2) используйте Comparator, когда я хочу указать и возраст, и имя. означает, что если Comparator обнаружит, что возраст совпадает, он будет сравнивать имя. - person RishiKesh Pathak; 08.12.2014
comment
@RishiKeshPathak: Ну, это больше, если вы используете Comparable, если есть только одна очевидная вещь для сравнения. И даже тогда вы можете просто написать компаратор. Если у вас есть две разные программы, использующие один и тот же класс, и одна хочет сортировать только по возрасту, а другая - по имени, по крайней мере одна из них должна будет использовать Comparator. - person Jon Skeet; 08.12.2014
comment
@JonSkeet, ты хочешь сказать, мы хороши даже без Comparable. Единственное преимущество, которое он дает - это более читаемый код? - person RishiKesh Pathak; 08.12.2014
comment
@RishiKeshPathak: Да, большинство API-интерфейсов поддерживают предоставление явного компаратора - просто это немного лишнее, если есть один очевидный порядок. - person Jon Skeet; 08.12.2014

Comparable позволяет классу реализовать собственное сравнение:

  • он относится к тому же классу (часто это является преимуществом)
  • может быть только одна реализация (поэтому вы не можете использовать ее, если вам нужны два разных случая)

Для сравнения, Comparator - это внешнее сравнение:

  • обычно он находится в уникальном экземпляре (либо в том же классе, либо в другом месте)
  • вы называете каждую реализацию так, как хотите
  • вы можете предоставить компараторы для классов, которые вы не контролируете
  • реализация пригодна для использования, даже если первый объект имеет значение NULL

В обеих реализациях вы по-прежнему можете выбрать то, что вы хотите сравнить. С помощью дженериков вы можете объявить это и проверить это во время компиляции. Это повышает безопасность, но также сложно определить подходящее значение.

В качестве ориентира я обычно использую самый общий класс или интерфейс, с которым можно было бы сравнить этот объект, во всех возможных вариантах использования ... Хотя не очень точное определение! :-(

  • Comparable<Object> позволяет использовать его во всех кодах во время компиляции (что хорошо, если необходимо, или плохо, если нет, и вы теряете ошибку времени компиляции); ваша реализация должна справляться с объектами и приводиться по мере необходимости, но надежно.
  • Comparable<Itself> наоборот очень строгий.

Забавно, когда вы подклассифицируете себя к подклассу, подкласс также должен быть сопоставимым и устойчивым к нему (иначе это нарушит принцип Лискова и даст вам ошибки во время выполнения).

person KLE    schedule 17.09.2009

java.lang.Comparable

  1. Чтобы реализовать интерфейс Comparable, класс должен реализовать единственный метод compareTo()

    int a.compareTo(b)

  2. Вы должны изменить класс, экземпляр которого вы хотите отсортировать. Таким образом, для каждого класса может быть создана только одна последовательность сортировки.

java.util.Comparator

  1. Чтобы реализовать интерфейс Comparator, класс должен реализовывать единственный метод compare()

    int compare (a,b)

  2. Вы создаете класс отдельно от класса, экземпляр которого вы хотите отсортировать. Так что для каждого класса можно создать несколько последовательностей сортировки.
person codiacTushki    schedule 17.05.2012

Comparable предназначен для обеспечения порядка по умолчанию для объектов данных, например, если объекты данных имеют естественный порядок.

Comparator представляет собой заказ для конкретного использования.

person starblue    schedule 17.09.2009

Comparable обычно предпочтительнее. Но иногда класс уже реализует Comparable, но вы хотите отсортировать по другому свойству. Тогда вы вынуждены использовать Comparator.

Некоторые классы фактически предоставляют Comparators для общих случаев; например, String по умолчанию -чувствителен при сортировке, но есть также статический Comparator с именем CASE_INSENSITIVE_ORDER.

person Michael Myers    schedule 17.09.2009
comment
Я не уверен, что согласен с предпочтением Comparable. Некоторые объекты обладают сильным чувством естественного порядка, а именно числа во всех их формах: натуральные числа, действительные числа, даты и т. Д. Но даже другие относительно примитивные объекты, такие как символьные строки, не имеют универсального применимого порядка. В случае более сложных объектов, таких как сущность из модели предметной области приложения, реализация Comparable обычно является ошибкой. Из-за их множества свойств слишком сложно предугадать, какой порядок будет требоваться чаще всего. - person erickson; 17.09.2009

Вот несколько различий между Comparator и Comparable, которые я нашел в Интернете:

  1. Если вы видите, то логическая разница между этими двумя: Comparator в Java сравнивает два предоставленных ему объекта, в то время как интерфейс Comparable сравнивает «эту» ссылку с указанным объектом.

  2. Comparable в Java используется для реализации естественного упорядочения объектов. В Java API String, Date и классы оболочки реализуют интерфейс Comparable.

  3. Если какой-либо класс реализует интерфейс Comparable в Java, тогда коллекция этого объекта List или Array может быть отсортирована автоматически с помощью метода Collections.sort () или Array.sort (), и объект будет отсортирован на основе естественного порядка, определенного методом CompareTo.

  4. Объекты, которые реализуют Comparable в Java, могут использоваться как ключи в отсортированной карте или элементы в отсортированном наборе, например TreeSet, без указания какого-либо Comparator.

сайт: Как использовать Comparator и Comparable в Java? С примером

Подробнее: Как использовать Comparator и Comparable в Java? Примером

person javapassion    schedule 05.09.2011

Comparable предназначен для объектов с естественным порядком. Сам объект знает, как его следует упорядочить.
Comparator предназначен для объектов без естественного порядка или когда вы хотите использовать другой порядок.

person Michael Lloyd Lee mlk    schedule 17.09.2009

Разница между интерфейсами Comparator и Comparable

Comparable используется для сравнения себя с другим объектом.

Comparator используется для сравнения двух типов данных, являющихся объектами.

person SravaniChowdary.Gorijavolu    schedule 25.10.2010

Если вы видите, то логическая разница между этими двумя: Comparator в Java сравнивает два предоставленных ему объекта, а Comparable интерфейс сравнивает "эту" ссылку с указанным объектом.

Comparable в Java используется для реализации естественного упорядочивания объектов. В Java API классы String, Date и оболочки реализуют интерфейс Comparable.

Если какой-либо класс реализует интерфейс Comparable в Java, тогда коллекция этого объекта либо List, либо Array может быть отсортирована автоматически с помощью метода Collections.sort() или Array.sort(), и объект будет отсортирован на основе естественного порядка, определенного методом compareTo.

Объекты, которые реализуют Comparable в Java, могут использоваться как ключи в отсортированной карте или элементы в отсортированном наборе, например, TreeSet, без указания какого-либо Comparator.

person Srinivas    schedule 14.02.2012

Моя аннотационная библиотека для реализации Comparable и Comparator:

public class Person implements Comparable<Person> {         
    private String firstName;  
    private String lastName;         
    private int age;         
    private char gentle;         

    @Override         
    @CompaProperties({ @CompaProperty(property = "lastName"),              
        @CompaProperty(property = "age",  order = Order.DSC) })           
    public int compareTo(Person person) {                 
        return Compamatic.doComparasion(this, person);         
    }  
} 

Щелкните ссылку, чтобы увидеть больше примеров. compamatic

person Jianmin Liu    schedule 08.01.2012
comment
Добро пожаловать в stackoverflow. Это старый вопрос, на который уже был дан ответ. Как правило, лучше не восстанавливать устаревшие темы, если ваш ответ не содержит чего-то существенно нового или отличного от предыдущих ответов. - person oers; 29.10.2012