У чому різниця між Java - х compare()і compareTo()методами? Ці методи дають однакову відповідь?
У чому різниця між Java - х compare()і compareTo()методами? Ці методи дають однакову відповідь?
Відповіді:
Від JavaNotes :
a.compareTo(b):
Порівнюваний інтерфейс: Порівняє значення та повертає int, який вказує, якщо значення порівнюють менше, рівне чи більше, ніж.
Якщо об'єкти вашого класу мають природний порядок , реалізуйте Comparable<T>інтерфейс та визначте цей метод. Всі класи Java , які мають природний порядок реалізації Comparable<T>- Приклад: String, обгортки класів ,BigInteger
compare(a, b):
Інтерфейс компаратора: Порівняє значення двох об'єктів. Це реалізується як частина Comparator<T>інтерфейсу, і типовим використанням є визначення одного або декількох малих класів утиліт, які реалізують це, для переходу до таких методів, як sort()або для використання, шляхом сортування структур даних, таких як TreeMapіTreeSet . Ви можете створити об’єкт компаратора для наступного:
sort()методу.Якщо об’єкти вашого класу мають один природний порядок сортування, вам може не знадобитися порівняння ().
Підсумок з http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html
Порівняний Порівняльний
об'єкт здатний порівнювати себе з іншим об'єктом.
Компаратор
Порівняльний об’єкт здатний порівнювати два різні об'єкти. Клас не порівнює його екземпляри, а деякі інстанції класу.
Використовуйте контексти випадку:
Порівняний інтерфейс
Метод рівнянь ==та != оператори перевіряють рівність / нерівність, але не дають можливості перевірити відносні значення .
Деякі класи (наприклад, String та інші класи з природним упорядкуванням) реалізують Comparable<T>інтерфейс, який визначає compareTo()метод.
Ви хочете реалізувати Comparable<T>у своєму класі, якщо ви хочете використовувати його з Collections.sort()абоArrays.sort() методами.
Визначення об'єкта компаратора
Ви можете створити компаратори, щоб сортувати будь-який довільний спосіб для будь-якого класу .
Наприклад, Stringклас визначає CASE_INSENSITIVE_ORDERкомпаратор .
Різниця між двома підходами може бути пов'язана з поняттям:
упорядкована колекція :
Коли колекція замовлена, це означає, що ви можете повторювати колекцію у визначеному (не випадковому) порядку (a Hashtable не впорядковано).
Колекція з природним замовленням не просто замовляється, а сортується . Визначити природний порядок може бути складно! (як у природному рядковому порядку) ).
Ще одна відмінність, яку зазначив HaveAGuess у коментарях :
Comparable знаходиться в реалізації та не видно з інтерфейсу, тож, сортуючи, ви насправді не знаєте, що буде. Comparator дає вам впевненість, що замовлення буде чітко визначено. compareTo()з Comparableінтерфейсу.
compare()з Comparatorінтерфейсу.
Обидва методи роблять те саме, але кожен інтерфейс використовується в дещо іншому контексті.
Порівнянні інтерфейс використовується для накласти природний порядок на об'єктах реалізує класу. 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, але ви все ще хочете їх порівняти. Тобто для сортування. Ви можете створити свій власний клас, який реалізує інтерфейс компаратора, і за його методом порівняння () ви реалізуєте логіку.
Порівняний інтерфейс містить метод, compareTo(obj)який називається, який бере лише один аргумент і порівнює себе з іншим екземпляром або об'єктами того ж класу.
Інтерфейс компаратора містить метод, compare(obj1,obj2)який називається, який бере два аргументи і порівнює значення двох об'єктів з одного і того ж або різних класів.
compareTo(T object)
походить від інтерфейсу java.lang.Comparable, реалізованого для порівняння цього об'єкта з іншим, щоб дати від'ємне значення int для цього об'єкта менше, 0, рівне або додатне значення більше, ніж інше. Це більш зручний метод порівняння, але він повинен бути реалізований у кожному класі, який ви хочете порівняти.
compare(T obj1, T obj2)
походить від інтерфейсу java.util.Comparator, реалізованого в окремому класі, який порівнює об'єкти іншого класу, щоб дати першому об’єкту від’ємне значення int менше, 0 для рівного, або додатне значення більше, ніж для другого об’єкта. Він потрібен, коли ви не можете зробити реалізацію класу сравнениеTo (), тому що він не може бути змінений. Він також використовується, коли потрібно по-різному порівнювати об'єкти, а не лише один (наприклад, за назвою чи віком).
Використовуючи компаратор, ми можемо мати n кількість логік порівняння, записаних для класу .
Напр
Для автомобільного класу
Ми можемо мати порівняльний клас для порівняння на основі номера моделі автомобіля. У нас також може бути порівняльний клас для порівняння на основі модельного року автомобіля.
Клас автомобіля
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();
}
}
Але це неможливо у випадку порівнянного інтерфейсу.
У випадку порівнянного інтерфейсу, ми можемо мати лише одну логіку в методі сравнениеTo () .
Взаємозв'язок об'єкта, що має цей метод, та його співробітників різні.
compareTo()є методом інтерфейсу Порівняльний , тому його використовують для порівняння ЦЕЕ екземпляра з іншим.
compare()є методом інтерфейсу Comparator , тому він використовується для порівняння двох різних примірників іншого класу один з одним.
Якщо ви хочете, реалізація Comparableозначає, що екземпляри класу можна легко порівняти.
Реалізація Comparatorозначає, що екземпляри підходять для порівняння різних об'єктів (інших класів).
Основна відмінність полягає у використанні інтерфейсів:
Порівняний (який має CompareTo ()) вимагає порівнювати об'єкти (щоб використовувати TreeMap або сортувати список) для реалізації цього інтерфейсу. Але що робити, якщо клас не реалізує програму Comparable, і ви не можете її змінити, оскільки вона є частиною сторонньої бібліотеки? Тоді вам доведеться реалізувати компаратор, який трохи менш зручний у використанні.
compareTo()викликається на одному об'єкті, щоб порівняти його з іншим об'єктом.
compare()викликається на якомусь об'єкті для порівняння двох інших об'єктів.
Різниця полягає в тому, де визначена логіка, яка робить фактичне порівняння.
Коли ви хочете сортувати Список, який включає Object Foo, клас Foo повинен реалізувати порівнянний інтерфейс, тому що метод сортування списку використовує цей метод.
Коли ви хочете написати клас Util, який порівнює два інші класи, ви можете реалізувати клас Comparator.
Ім’я таблиці службовців , DoB, Заробітна плата
Томаш, 10.10.1982, 300
Даніель, 11.11.1990, 400
Квам, 2.10.1998, 520
Інтерфейс порівняння дозволяє сортувати список об’єктів, наприклад, Співробітники з посиланням на одне первинне поле - наприклад, ви можете сортувати за назвою чи заробітною платою методом CompareTo ()
emp1.getName().compareTo(emp2.getName())
Більш гнучкий інтерфейс для таких вимог надає інтерфейс компаратора , єдиним методом якого є порівняння ()
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
}
}
Ще один момент:
compareTo()від Comparableінтерфейсу і compare()від Comparatorінтерфейсу.Comparableвикористовується для визначення замовлення за замовчуванням для об'єктів у класі, тоді 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Покемона. (У лямбда this- це екземпляр зовнішнього класу в області лямбда, як визначено в тексті програми.) Отже, це не летить , і ми повинні використовувати 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)заяві беруть лише Object; примітивне заборонено. Наприклад
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();
}