В чем разница между 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()
метод. - Системный класс Для предоставления методов сравнения для классов, которые вы не можете контролировать. Например, вы можете определить компаратор для строк, которые сравнивают их по длине.
- Шаблон стратегии Для реализации шаблона стратегии, в котором вы хотите представить алгоритм в виде объекта, который можно передать в качестве параметра, сохранить в структуре данных и т. Д.
- Многократные сравнения. Предоставить несколько разных способов что-то отсортировать. Например, вы можете отсортировать класс Person по имени, идентификатору, возрасту, росту и т. Д. Для каждого из них вы должны определить компаратор для передачи в
Если у ваших объектов класса есть один естественный порядок сортировки, вам может не понадобиться сравнение ().
Резюме от 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();
}