Когда использовать Comparable и Comparator

У меня есть список объектов, которые мне нужно сортировать по полю, например Score. Не задумываясь, я написал новый класс, который реализует Comparator, который выполняет эту задачу и работает.

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

  • Что я сделал приемлемым как практика?

  • Правильный подход "Сначала нужно реализовать класс Comparable (для естественного упорядочения), и если требуется альтернативное сопоставление полей, тогда создайте новый класс, который реализует Comparator"?

  • Если (2) выше верно, то означает ли это, что следует реализовать Компаратор только после того, как у них есть реализация класса Comparable? (Предполагая, что у меня есть оригинальный класс).

96
15 февр. '10 в 18:12
источник поделиться
20 ответов

Я бы сказал, что объект должен реализовывать Comparable, если это естественный естественный способ сортировки класса, и кому-то нужно было бы отсортировать класс, как правило, хотелось бы сделать это таким образом.

Если, однако, сортировка была необычным использованием класса, или сортировка имеет смысл только для конкретного варианта использования, то лучше использовать Компаратор.

Иными словами, с учетом имени класса, ясно, как сопоставимый будет сортироваться, или вам нужно прибегнуть к чтению javadoc? Если это последний, то вероятность того, что каждый будущий пример использования сортировки потребует компаратора, в этот момент реализация сопоставимого может замедлить пользователей класса, а не ускорять их.

75
15 февр. '10 в 18:18
источник

Связанные вопросы


Похожие вопросы

Используйте Comparable, если вы хотите определить поведение по умолчанию (естественное) упорядочения рассматриваемого объекта, общепринятой практикой является использование технического или естественного (базы данных?) идентификатора объекта для этого.

Используйте Comparator, если вы хотите определить поведение упорядочения внешнего контролируемого, это может переопределить порядок по умолчанию поведение.

120
15 февр. '10 в 18:17
источник

Используйте Comparable:

  • если объект находится под вашим контролем.
  • если поведение сравнения является основным поведением сравнения.

Используйте Comparator:

  • если объект находится вне вашего контроля, и вы не можете заставить их реализовать Comparable.
  • если вы хотите сравнить поведение, отличное от по умолчанию (которое указано в Comparable).
51
15 февр. '10 в 18:21
источник

Comparable - java.lang.Comparable: int compareTo(Object o1)

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

  • Способен сравнивать текущий объект с предоставленным объектом.
  • Используя это, мы можем реализовать only one sort sequence на основе свойств экземпляров. EX: Person.id
  • В некоторых предопределенных классах, таких как String, Wrapper, Date, Calendar, реализован Comparable интерфейс.

Компаратор - java.util.Comparator: int compare(Object o1, Object o2)

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

  • Способен сравнивать любые два объекта одного типа.
  • Используя это, мы можем реализовать many sort sequence и именовать каждую, основываясь на свойствах экземпляров. Person.id, Person.name, Person.age: Person.id, Person.name, Person.age
  • Мы можем реализовать интерфейс Comparator для наших предопределенных классов для индивидуальной сортировки.

Пример:

public class Employee implements Comparable<Employee> {

    private int id;
    private String name;
    private int age;
    private long salary;

    // Many sort sequences can be created with different names.
    public static Comparator<Employee> NameComparator = new Comparator<Employee>() {         
        @Override
        public int compare(Employee e1, Employee e2) {
            return e1.getName().compareTo(e2.getName());
        }
    };
    public static Comparator<Employee> idComparator = new Comparator<Employee>() {       
        @Override
        public int compare(Employee e1, Employee e2) {
            return Integer.valueOf(e1.getId()).compareTo(Integer.valueOf(e2.getId()));
        }
    };

    public Employee() { }
    public Employee(int id, String name, int age, long salary){
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
    // setters and getters.

    // Only one sort sequence can be created with in the class.
    @Override
    public int compareTo(Employee e) {
    //return Integer.valueOf(this.id).compareTo(Integer.valueOf(e.id));
    //return Character.toString(this.name.charAt(0)).compareToIgnoreCase(Character.toString(e.name.charAt(0)));
        if (this.id > e.id) {
            return 1;
        }else if(this.id < e.id){
            return -1;
        }else {
            return Character.toString(this.name.charAt(0)).compareToIgnoreCase(Character.toString(e.name.charAt(0)));
        }

    }   

    public static void main(String[] args) {

        Employee e1 = new Employee(5, "Yash", 22, 1000);
        Employee e2 = new Employee(8, "Tharun", 24, 25000);

        List<Employee> list = new ArrayList<Employee>();
        list.add(e1);
        list.add(e2);
        Collections.sort(list); // call @compareTo(o1)
        Collections.sort(list, Employee.nameComparator); // call @compare (o1,o2)
        Collections.sort(list, Employee.idComparator); // call @compare (o1,o2)
    }
}
  • Для настраиваемой сортировки мы используем компаратор @compare (o1, o2), а для других сценариев - сопоставимый @compareTo (o1), без изменения кода, если мы хотим отсортировать более одного поля, тогда мы используем компаратор.

Для Java 8 Lambda: Comparator см. Мой пост.

18
06 июля '15 в 14:24
источник

Сопоставимый должен использоваться, когда вы сравниваете экземпляры одного и того же класса.

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

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

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

9
06 июля '11 в 11:23
источник

Компаратор делает все, что сопоставимо, плюс больше.

| | Comparable | Comparator ._______________________________________________________________________________ Is used to allow Collections.sort to work | yes | yes Can compare multiple fields | yes | yes Lives inside the class you’re comparing and serves | | as a "default" way to compare | yes | yes Can live outside the class you’re comparing | no | yes Can have multiple instances with different method names | no | yes Input arguments can be a list of | just Object| Any type Can use enums | no | yes

Я нашел лучший подход к использованию компараторов в качестве анонимных классов следующим образом:

private static void sortAccountsByPriority(List<AccountRecord> accounts) {
    Collections.sort(accounts, new Comparator<AccountRecord>() {

        @Override
        public int compare(AccountRecord a1, AccountRecord a2) {
            return a1.getRank().compareTo(a2.getRank());
        }
    });
}

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

  • sortAccountsByPriority
  • sortAccountsByType
  • sortAccountsByPriorityAndType

    и т.д...

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

9
16 нояб. '14 в 11:27
источник

Я бы сказал:

  • если сравнение является интуитивным, тогда, во всяком случае, реализовать Comparable
  • если неясно, насколько ваше сравнение интуитивно понятно, используйте Comparator, поскольку он больше явный и, следовательно, более ясный для бедной души, который должен поддерживать код
  • Если возможно более одного интуитивного сравнения, я бы предпочел компаратор, возможно построить методом factory в сравниваемом классе.
  • Если сравнение является специальной целью, используйте Comparator
8
15 февр. '10 в 18:31
источник

Следующие пункты помогут вам решить, в каких ситуациях следует использовать Comparable и в котором Comparator:

1) Доступность кода

2) Один или несколько критериев сортировки

3) Arays.sort() и Collection.sort()

4) В качестве ключей в SortedMap и SortedSet

5) Больше Число классов В сравнении с гибкостью

6) Сравнение между классами

7) Естественный порядок

Для более подробной статьи вы можете сослаться на Когда использовать сопоставимые и когда использовать компаратор

4
26 июля '15 в 5:41
источник
  • Если на момент написания класса у вас есть только один случай сортировки используйте Comparable.
  • Только когда у вас более одного стратегия сортировки Компаратор.
4
15 февр. '10 в 19:15
источник

Если вам нужна сортировка естественного порядка - User Comparable Если вам нужна индивидуальная сортировка заказов - используйте компаратор

Пример:

Class Employee{
private int id;
private String name;
private String department;
}

Естественный порядок сортировки будет основан на идентификаторе, потому что он будет уникальным, и пользовательский порядок сортировки будет именем и департаментом.

Refrences:
Когда класс должен быть сравнимым и/или компаратором? http://javarevisited.blogspot.com/2011/06/comparator-and-comparable-in-java.html

3
12 окт. '11 в 13:02
источник

Здесь был аналогичный вопрос: Когда класс должен быть сравнимым и/или компаратором?

Я бы сказал следующее: Внедрить Comparable для чего-то вроде естественного упорядочения, например. на основе внутреннего идентификатора

Внедрить Компаратор, если у вас есть более сложный алгоритм сравнения, например. несколько полей и т.д.

3
15 февр. '10 в 18:17
источник

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

Основное различие между Comparable и Comparator:

+------------------------------------------------------------------------------------+
¦               Comparable                ¦                Comparator                ¦
¦-----------------------------------------+------------------------------------------¦
¦ java.lang.Comparable                    ¦ java.util.Comparator                     ¦
¦-----------------------------------------+------------------------------------------¦
¦ int objOne.compareTo(objTwo)            ¦ int compareTo(objOne, objTwo)            ¦
¦-----------------------------------------+------------------------------------------¦
¦ Negative, if objOne < objTwo            ¦ Same as Comparable                       ¦
¦ Zero,  if objOne == objTwo              ¦                                          ¦
¦ Positive,  if objOne > objTwo           ¦                                          ¦
¦-----------------------------------------+------------------------------------------¦
¦ You must modify the clas whose          ¦ You build a class separate from to sort. ¦
¦ instances you want to sort.             ¦ the class whose instances you want       ¦
¦-----------------------------------------+------------------------------------------¦
¦ Only one sort sequemce can be created   ¦ Many sort sequences can be created       ¦
¦-----------------------------------------+------------------------------------------¦
¦ Implemented frequently in the API by:   ¦ Meant to be implemented to sort          ¦
¦ String, Wrapper classes, Date, Calandar ¦ instances of third-party classes.        ¦
+------------------------------------------------------------------------------------+
2
22 мая '18 в 9:21
источник

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

Компаратор:
Всякий раз, когда мы хотим хранить однородные и гетерогенные элементы, и мы хотим сортировать по умолчанию, настроенный порядок сортировки, мы можем перейти на comparator интерфейс.

2
12 дек. '11 в 6:18
источник

Моя потребность была сортировкой по дате.

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

public int compareTo(GoogleCalendarBean o) {
    // TODO Auto-generated method stub
    return eventdate.compareTo(o.getEventdate());
}

Одно ограничение с помощью Comparable состоит в том, что они не могут использоваться для Коллекций, отличных от List.

0
29 окт. '12 в 11:00
источник

Меня попросили отсортировать определенный диапазон чисел в лучшем, чем nlogn time, в одном из интервью. (Не использовать сортировку)

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

0
15 июля '15 в 21:30
источник

Если вы владеете классом лучше, используйте Сопоставимый. Обычно Компаратор используется, если вы не владеете классом, но вы должны использовать его TreeSet или TreeMap, потому что Comparator может быть передан как параметр в конкатструктор TreeSet или TreeMap. Вы можете увидеть, как использовать Comparator и Comparable в http://preciselyconcise.com/java/collections/g_comparator.php

0
20 мая '14 в 15:02
источник

Comparable - это естественный порядок сортировки по умолчанию, при условии, что числовые значения имеют возрастание, а строки - алфавитный порядок. например:

Treeset t=new Treeset();
t.add(2);
t.add(1);
System.out.println(t);//[1,2]

Comparator - это пользовательский порядок сортировки, реализованный в пользовательском классе myComparator путем переопределения метода сравнения, например:

Treeset t=new Treeset(new myComparator());
t.add(55);
t.add(56);
class myComparator implements Comparator{
public int compare(Object o1,Object o2){
//Descending Logic
}
}
System.out.println(t);//[56,55]
0
13 сент. '18 в 19:18
источник

Очень простой подход состоит в том, чтобы предположить, что рассматриваемый класс сущности должен быть представлен в базе данных, а затем в таблице базы данных вам нужен индекс, состоящий из полей класса сущности? Если да, то реализуйте сопоставимые и используйте поле (индексы) индекса для естественного порядка сортировки. Во всех остальных случаях используйте компаратор.

-1
12 окт. '11 в 8:58
источник

Моя аннотация lib для реализации 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);         
    }  
}

Нажмите ссылку, чтобы увидеть больше примеров. http://code.google.com/p/compamatic/wiki/CompamaticByExamples

-2
08 янв. '12 в 4:42
источник

Comparable и Comparator являются интерфейсами и могут использоваться для сортировки элементов коллекции.

Однако существует много различий между интерфейсами Comparable и Comparator, которые приведены по ссылке ниже:

http://techgyani.co.in/java/difference-between-comparable-and-comparator/

-2
20 янв. '19 в 14:45
источник

Посмотрите другие вопросы по меткам или Задайте вопрос