Для чого Comparableвикористовується Java ? Чому хтось реалізовує Comparableв класі? Який приклад із реального життя, де потрібно реалізувати порівнянне?
Для чого Comparableвикористовується Java ? Чому хтось реалізовує Comparableв класі? Який приклад із реального життя, де потрібно реалізувати порівнянне?
Відповіді:
Ось зразок реального життя. Зверніть увагу, що Stringтакож реалізує Comparable.
class Author implements Comparable<Author>{
String firstName;
String lastName;
@Override
public int compareTo(Author other){
// compareTo should return < 0 if this is supposed to be
// less than other, > 0 if this is supposed to be greater than
// other and 0 if they are supposed to be equal
int last = this.lastName.compareTo(other.lastName);
return last == 0 ? this.firstName.compareTo(other.firstName) : last;
}
}
пізніше ..
/**
* List the authors. Sort them by name so it will look good.
*/
public List<Author> listAuthors(){
List<Author> authors = readAuthorsFromFileOrSomething();
Collections.sort(authors);
return authors;
}
/**
* List unique authors. Sort them by name so it will look good.
*/
public SortedSet<Author> listUniqueAuthors(){
List<Author> authors = readAuthorsFromFileOrSomething();
return new TreeSet<Author>(authors);
}
last?
Порівняльне визначає природне впорядкування. Це означає, що ви визначаєте це, коли один об'єкт слід вважати "меншим" або "більшим за".
Припустимо, у вас є купа цілих чисел, і ви хочете їх сортувати. Це досить просто, просто покладіть їх у відсортовану колекцію, правда?
TreeSet<Integer> m = new TreeSet<Integer>();
m.add(1);
m.add(3);
m.add(2);
for (Integer i : m)
... // values will be sorted
Але тепер припустимо, що у мене є якийсь спеціальний об'єкт, де сортування має для мене сенс, але не визначене. Скажімо, у мене є дані, що представляють райони за поштовим індексом з щільністю населення, і я хочу їх сортувати за щільністю:
public class District {
String zipcode;
Double populationDensity;
}
Тепер найпростіший спосіб їх сортування - це визначити їх за допомогою природного впорядкування, застосувавши Comparable, а це означає, що існує стандартний спосіб визначення цих об'єктів для замовлення:
public class District implements Comparable<District>{
String zipcode;
Double populationDensity;
public int compareTo(District other)
{
return populationDensity.compareTo(other.populationDensity);
}
}
Зауважте, що ви можете зробити рівнозначну річ, визначивши компаратор. Різниця полягає в тому, що компаратор визначає логіку впорядкування поза об'єктом . Можливо, в окремому процесі мені потрібно замовити ті самі об'єкти за поштовим індексом - в такому випадку впорядкування не обов'язково є властивістю об'єкта або відрізняється від природного впорядкування об'єктів. Ви можете використовувати зовнішній компаратор для визначення замовного замовлення на цілі числа, наприклад, сортуючи їх за алфавітним значенням.
В основному логіка впорядкування повинна десь існувати. Це може бути -
в самому об'єкті, якщо він природно порівнянний (розширює Порівняльні -eg цілі числа)
поставляється у зовнішньому компараторі, як у наведеному вище прикладі.
TreeSet<Integer>замість цього TreeMap<Integer>, оскільки останній не існує, TreeMaps - це завжди <Key,Value>-пари. Доречно, гіпотетична TreeMap<District, Object>спрацювала б лише в тому випадку, якщо Район реалізує Порівняльне, правда? Ще намагаюся зрозуміти це
Цитується з javadoc;
Цей інтерфейс накладає загальне впорядкування на об'єкти кожного класу, який його реалізує. Це впорядкування називається природним впорядкуванням класу, а метод порівняння класу - природним методом порівняння.
Списки (та масиви) об'єктів, що реалізують цей інтерфейс, можна автоматично сортувати за Collections.sort (та Arrays.sort). Об'єкти, що реалізують цей інтерфейс, можуть використовуватися як ключі в відсортованій карті або як елементи в відсортованому наборі без необхідності вказувати компаратор.
Редагувати: .. і зробив важливий трохи сміливим.
Те, що клас реалізує, Comparableозначає, що ви можете взяти два об’єкти з цього класу та порівняти їх. Деякі класи, як-от певні колекції (функція сортування в колекції), які зберігають об'єкти, щоб покладатися на їх порівнянність (для сортування потрібно знати, який об’єкт є "найбільшим" тощо).
Більшість прикладів, наведених вище, показують, як повторно використовувати існуючий порівняний об'єкт у функції CompareTo. Якщо ви хочете реалізувати своє власне CompareTo, коли ви хочете порівняти два об'єкти одного класу, скажіть об’єкт AirlineTicket, який ви хочете б сортувати за ціною (менше займає перше місце), а потім числом зупинки (знову менше, менше Ви посіли перше місце) Ви зробите наступне:
class AirlineTicket implements Comparable<Cost>
{
public double cost;
public int stopovers;
public AirlineTicket(double cost, int stopovers)
{
this.cost = cost; this.stopovers = stopovers ;
}
public int compareTo(Cost o)
{
if(this.cost != o.cost)
return Double.compare(this.cost, o.cost); //sorting in ascending order.
if(this.stopovers != o.stopovers)
return this.stopovers - o.stopovers; //again, ascending but swap the two if you want descending
return 0;
}
}
Простий спосіб здійснити декілька порівнянь поля - це Guava's ComparingChain - тоді ви можете сказати
public int compareTo(Foo that) {
return ComparisonChain.start()
.compare(lastName, that.lastName)
.compare(firstName, that.firstName)
.compare(zipCode, that.zipCode)
.result();
}
замість
public int compareTo(Person other) {
int cmp = lastName.compareTo(other.lastName);
if (cmp != 0) {
return cmp;
}
cmp = firstName.compareTo(other.firstName);
if (cmp != 0) {
return cmp;
}
return Integer.compare(zipCode, other.zipCode);
}
}
Порівняльний використовується для порівняння примірників вашого класу. Ми можемо порівняти екземпляри багатьма способами, тому нам потрібно реалізувати метод compareTo, щоб знати, як (атрибути) ми хочемо порівняти екземпляри.
Dog клас:package test;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Dog d1 = new Dog("brutus");
Dog d2 = new Dog("medor");
Dog d3 = new Dog("ara");
Dog[] dogs = new Dog[3];
dogs[0] = d1;
dogs[1] = d2;
dogs[2] = d3;
for (int i = 0; i < 3; i++) {
System.out.println(dogs[i].getName());
}
/**
* Output:
* brutus
* medor
* ara
*/
Arrays.sort(dogs, Dog.NameComparator);
for (int i = 0; i < 3; i++) {
System.out.println(dogs[i].getName());
}
/**
* Output:
* ara
* medor
* brutus
*/
}
}
Main клас:package test;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Dog d1 = new Dog("brutus");
Dog d2 = new Dog("medor");
Dog d3 = new Dog("ara");
Dog[] dogs = new Dog[3];
dogs[0] = d1;
dogs[1] = d2;
dogs[2] = d3;
for (int i = 0; i < 3; i++) {
System.out.println(dogs[i].getName());
}
/**
* Output:
* brutus
* medor
* ara
*/
Arrays.sort(dogs, Dog.NameComparator);
for (int i = 0; i < 3; i++) {
System.out.println(dogs[i].getName());
}
/**
* Output:
* ara
* medor
* brutus
*/
}
}
Ось хороший приклад, як використовувати порівнянне в Java:
http://www.onjava.com/pub/a/onjava/2003/03/12/java_comp.html?page=2
Коли ви реалізуєте Comparableінтерфейс, вам потрібно реалізувати метод compareTo(). Він вам потрібен для порівняння об'єктів, щоб використовувати, наприклад, метод сортування ArrayListкласу. Вам потрібен спосіб порівняння ваших об'єктів, щоб мати можливість їх сортувати. Отже, вам потрібен спеціальний compareTo()метод у вашому класі, щоб ви могли використовувати його з ArrayListметодом сортування. ThecompareTo() метод повертає -1,0,1.
Я щойно прочитав відповідний розділ у Java Head 2.0, я все ще вчуся.
Гаразд, але чому б просто не визначити compareTo()метод без реалізації порівнянного інтерфейсу. Наприклад клас, Cityвизначений його nameта temperatureта
public int compareTo(City theOther)
{
if (this.temperature < theOther.temperature)
return -1;
else if (this.temperature > theOther.temperature)
return 1;
else
return 0;
}