В чем разница между Compare() и CompareTo()?

В чем разница между Java compare() а также compareTo() методы? Эти методы дают один и тот же ответ?

15 ответов

Решение

Из JavaNotes:

  • a.compareTo(b):
    Сопоставимый интерфейс: сравнивает значения и возвращает int, который сообщает, сравниваются ли значения меньше, равно или больше чем.
    Если ваши объекты класса имеют естественный порядок, реализуйте Comparable<T> интерфейс и определить этот метод. Все классы Java, которые имеют естественную реализацию порядка Comparable<T> - Пример: String, классы обертки, BigInteger

  • compare(a, b):
    Интерфейс компаратора: сравнивает значения двух объектов. Это реализовано как часть Comparator<T> интерфейс, и типичное использование состоит в том, чтобы определить один или несколько небольших служебных классов, которые реализуют это, чтобы перейти к таким методам, как sort() или для использования путем сортировки структур данных, таких как TreeMap а также TreeSet, Возможно, вы захотите создать объект Comparator для следующего:

    • Многократные сравнения. Предоставить несколько разных способов что-то отсортировать. Например, вы можете отсортировать класс Person по имени, идентификатору, возрасту, росту и т. Д. Для каждого из них вы должны определить компаратор для передачи в sort() метод.
    • Системный класс Для предоставления методов сравнения для классов, которые вы не можете контролировать. Например, вы можете определить компаратор для строк, которые сравнивают их по длине.
    • Шаблон стратегии Для реализации шаблона стратегии, в котором вы хотите представить алгоритм в виде объекта, который можно передать в качестве параметра, сохранить в структуре данных и т. Д.

Если у ваших объектов класса есть один естественный порядок сортировки, вам может не понадобиться сравнение ().


Резюме от http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html

сравнимый
Сопоставимый объект способен сравнивать себя с другим объектом.

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


Контексты использования:

Сопоставимый интерфейс

Метод равных и == а также != операторы проверяют на равенство / неравенство, но не предоставляют способ проверки на относительные значения.
Некоторые классы (например, String и другие классы с естественным порядком) реализуют Comparable<T> интерфейс, который определяет compareTo() метод.
Вы захотите реализовать Comparable<T> в вашем классе, если вы хотите использовать его с Collections.sort() или же Arrays.sort() методы.

Определение объекта Comparator

Вы можете создавать компараторы для сортировки любым произвольным способом для любого класса.
Например, String класс определяет CASE_INSENSITIVE_ORDER компаратор


Разница между этими двумя подходами может быть связана с понятием:
Заказанная коллекция:

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

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


Еще одно отличие, указанное HaveAGuess в комментариях:

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

compareTo() от Comparable интерфейс.

compare() от Comparator интерфейс.

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

Интерфейс Comparable используется для наложения естественного порядка на объекты класса реализации. compareTo() Метод называется методом естественного сравнения. Интерфейс Comparator используется для наложения полного упорядочения на объекты реализующего класса. Для получения дополнительной информации см. Ссылки, чтобы точно определить, когда использовать каждый интерфейс.

сходства:
Оба являются пользовательскими способами сравнения двух объектов.
Оба возвращают int описывая отношения между двумя объектами.

Отличия: метод compare() это метод, который вы обязаны реализовать, если вы реализуете Comparator интерфейс. Это позволяет вам передавать два объекта в метод и возвращает int описывая их отношения.

Comparator comp = new MyComparator();
int result = comp.compare(object1, object2);

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

String s = "hi";
int result = s.compareTo("bye");

Резюме:
По сути, это два разных способа сравнения вещей.

Методы не должны давать одинаковые ответы. Это зависит от того, какие объекты / классы вы им называете.

Если вы реализуете свои собственные классы, которые, как вы знаете, вы хотите сравнить на каком-то этапе, вы можете попросить их реализовать интерфейс Comparable и соответственно реализовать метод compareTo().

Если вы используете некоторые классы из API, которые не реализуют интерфейс Comparable, но вы все равно хотите сравнить их. Т.е. для сортировки. Вы можете создать свой собственный класс, который реализует интерфейс Comparator, а в его методе Compare() вы реализуете логику.

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

Например

Для класса автомобиля

Мы можем иметь класс Comparator для сравнения на основе номера модели автомобиля. У нас также может быть класс Comparator для сравнения в зависимости от года выпуска автомобиля.

Класс автомобиля

public class Car  {

    int modelNo;

    int modelYear;

    public int getModelNo() {
        return modelNo;
    }

    public void setModelNo(int modelNo) {
        this.modelNo = modelNo;
    }

    public int getModelYear() {
        return modelYear;
    }

    public void setModelYear(int modelYear) {
        this.modelYear = modelYear;
    }

}

Компаратор № 1 на основе модели №

public class CarModelNoCompartor implements Comparator<Car>{

    public int compare(Car o1, Car o2) {

        return o1.getModelNo() - o2.getModelNo();
    }

}

Компаратор № 2 на основе модельного года

public class CarModelYearComparator implements Comparator<Car> {

    public int compare(Car o1, Car o2) {

        return o1.getModelYear() - o2.getModelYear();
    }

}

Но это невозможно в случае с сопоставимым интерфейсом.

В случае интерфейса Comparable у нас может быть только одна логика в методе CompareTo().

Сопоставимый интерфейс содержит метод, называемый compareTo(obj) который принимает только один аргумент и сравнивает себя с другим экземпляром или объектами того же класса.

Интерфейскомпаратора содержит метод, называемый compare(obj1,obj2) который принимает два аргумента и сравнивает значение двух объектов из одного или разных классов.

compareTo(T object)

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

compare(T obj1, T obj2)

происходит из интерфейса java.util.Comparator, реализованного в отдельном классе, который сравнивает объекты другого класса, чтобы получить отрицательное значение типа int для первого объекта меньше, чем 0, для равных, или положительное значение для большего, чем второй объект. Это необходимо, когда вы не можете сделать класс реализующим CompareTo(), потому что он не может быть изменен. Он также используется, когда вам нужны разные способы сравнения объектов, а не только один (например, по имени или возрасту).

Отношения объекта, имеющего этот метод, и его соавторов различны.

compareTo() является методом интерфейса Comparable, поэтому он используется для сравнения ЭТОГО экземпляра с другим.

compare() является методом интерфейса Comparator, поэтому он используется для сравнения двух разных экземпляров другого класса друг с другом.

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

Основное отличие заключается в использовании интерфейсов:

Comparable (который имеет compareTo()) требует, чтобы объекты сравнивались (чтобы использовать TreeMap или отсортировать список) для реализации этого интерфейса. Но что, если класс не реализует Comparable, и вы не можете изменить его, потому что он является частью сторонней библиотеки? Затем вы должны реализовать Comparator, который немного менее удобен в использовании.

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

Разница в том, где определяется логика, которая делает фактическое сравнение.

Еще один момент:

  • compareTo() от Comparable интерфейс и compare() от Comparator интерфейс.
  • Comparable используется для определения порядка по умолчанию для объектов в классе, в то время как Comparator используется для определения пользовательского порядка, передаваемого методу.

Использовать интерфейс Comparable для сортировки по нескольким значениям, таким как age,name,dept_name... Для одного значения используйте интерфейс Comparator

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

class Pokemon {
    int healthPoints;
    int attackDamage;
    public void battle (Comparable<Pokemon> comparable, Pokemon opponent) {
        if (comparable.compareTo(opponent) > 0) { //comparable needs to, but cannot, access this.healthPoints for example
            System.out.println("battle won");
        } else {
            System.out.println("battle lost");
        }
    }
}

comparable будет лямбда или объект, и нет никакого способа для comparable чтобы получить доступ к полям this Pokemon. (В лямбде this ссылается на экземпляр внешнего класса в области видимости лямбды, как определено в тексте программы.) Так что это не летит, и мы должны использовать Comparator с двумя аргументами.

Стол сотрудника
Имя, DoB, Зарплата
Томас, 2/10/1982, 300
Даниил, 3/11/1990, 400
Кваме, 10/10/1998, 520

Интерфейс Comparable позволяет сортировать список объектов, например, "Сотрудники", со ссылкой на одно основное поле - например, вы можете сортировать по имени или по зарплате с помощью метода CompareTo()

emp1.getName().compareTo(emp2.getName())

Более гибкий интерфейс для таких требований обеспечивается интерфейсом Comparator, единственным методом которого является compare()

public interface Comparator<Employee> {
 int compare(Employee obj1, Employee obj2);
}

Образец кода

public class NameComparator implements Comparator<Employee> {

public int compare(Employee e1, Employee e2) {
     // some conditions here
        return e1.getName().compareTo(e2.getName()); // returns 1 since (T)omas > (D)an 
    return e1.getSalary().compareTo(e2.getSalary()); // returns -1 since 400 > 300
}

}

Когда вы хотите отсортировать List, который включает Object Foo, класс Foo должен реализовать интерфейс Comparable, потому что метод сортировки List использует этот метод.

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

Important Answar
String name;
int roll;

public int compare(Object obj1,Object obj2) { // For Comparator interface
    return obj1.compareTo(obj1);
}

public int compareTo(Object obj1) { // For Comparable Interface
    return obj1.compareTo(obj);
}

Здесь в return obj1.compareTo(obj1) или же return obj1.compareTo(obj) оператор только взять объект; Примитив не допускается. Например

name.compareTo(obj1.getName()) // Correct Statement.

Но

roll.compareTo(obj1.getRoll()) 
// Wrong Statement Compile Time Error Because roll 
// is not an Object Type, it is primitive type.

зовут String Object, чтобы он работал. Если вы хотите отсортировать число учеников, используйте код ниже.

public int compareTo(Object obj1) { // For Comparable Interface
    Student s = (Student) obj1;
    return rollno - s.getRollno();
}  

или же

public int compare(Object obj1,Object obj2) { // For Comparator interface
    Student s1 = (Student) obj1;
    Student s2 = (Student) obj2;
    return s1.getRollno() - s2.getRollno();
}  
Другие вопросы по тегам