Java Comparable i Comparator razlike
U prethodnom učenju prioritetni red, pomenuli smo Comparable i Comparator, pa nastavimo sa perspektive intervjutera.
Onog dana, Xiao Er je išao na intervju u Ma Fengwo, a intervjuer Wang Yi ga je odmah pitao: Koji su razlike između Comparable i Comparator? Xiao Er se smejao, jer pre tri godine, 2021. godine, na Ergeovoj Java putanji napredovanja je video ovo pitanje😆.
Comparable i Comparator su dva Java interfejsa, i iz samog imena možemo pročitati njihovu sličnost: poređenje dva objekta na određeni način.
Ali koje su u suštini razlike između njih? Dođite sa mnom, krećemo u napredovanje!
01,Comparable
Comparable interfejs je vrlo jednostavan, izvorni kod je prikazan ispod.
public interface Comparable<T> {
int compareTo(T t);
}Ako klasa implementira Comparable interfejs (samo treba uraditi jednu stvar, prepisati compareTo() metod), onda može porediti objekte koje je napravila prema sopstvenim pravilima. Evo jednog primera.
public class Cmower implements Comparable<Cmower> {
private int age;
private String name;
public Cmower(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public int compareTo(Cmower o) {
return this.getAge() - o.getAge();
}
public static void main(String[] args) {
Cmower wanger = new Cmower(19,"Chenmo Wang Er");
Cmower wangsan = new Cmower(16,"Chenmo Wang San");
if (wanger.compareTo(wangsan) < 0) {
System.out.println(wanger.getName() + "je mlađi i sposobniji");
} else {
System.out.println(wangsan.getName() + "je mlađi i sposobniji");
}
}
}U gornjem primeru, napravio sam klasu Cmower koja ima dva polja: age i name. Cmower klasa implementira Comparable interfejs i prepisuje compareTo() metod.
Rezultat programa je "Chenmo Wang San je mlađi i sposobniji", jer je tri godine mlađi od Chenmo Wang Er. Da li ima dokaza za ovaj rezultat?
Dokaz je u compareTo() metodu, čija povratna vrednost može biti negativan broj, nula ili pozitivan broj, što znači da je objekat manji, jednak ili veći od objekta sa kojim se poredi prema pravilima sortiranja. Ako se ne može porediti tip navedenog objekta sa ovim objektom, baca se ClassCastException izuzetak (od kada postoje generici, ovo se retko dešava).
02,Comparator
Comparator interfejs je mnogo kompleksniji od Comparable, ali osnovne metode su samo dve, pogledajmo izvorni kod.
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}Prva metoda compare(T o1, T o2) vraća negativan broj, nulu ili pozitivan broj, što znači da je prvi objekat manji, jednak ili veći od drugog objekta.
Druga metoda equals(Object obj) zahteva Object kao parametar i proverava da li je taj Object jednak sa Comparatorom.
Ponekad želimo da klasa ostane u originalnom obliku, ne želimo da implementira Comparable interfejs, ali i dalje moramo da ih poredimo, šta da radimo?
Onda nam Comparator pomaže, pogledajmo primer.
1)Nepromenjena Cmower klasa.
public class Cmower {
private int age;
private String name;
public Cmower(int age, String name) {
this.age = age;
this.name = name;
}
}Cmower klasa ima dva polja: age i name, što znači da se ova klasa može sortirati prema age ili name.
2)Pogledajmo implementaciju Comparator interfejsa.
public class CmowerComparator implements Comparator<Cmower> {
@Override
public int compare(Cmower o1, Cmower o2) {
return o1.getAge() - o2.getAge();
}
}Poređenje prema age. Naravno, možete implementirati i drugi komparator za prirodno sortiranje prema name, kao u primeru ispod.
public class CmowerNameComparator implements Comparator<Cmower> {
@Override
public int compare(Cmower o1, Cmower o2) {
if (o1.getName().hashCode() < o2.getName().hashCode()) {
return -1;
} else if (o1.getName().hashCode() == o2.getName().hashCode()) {
return 0;
}
return 1;
}
}3)Pogledajmo test klasu.
Cmower wanger = new Cmower(19,"Chenmo Wang Er");
Cmower wangsan = new Cmower(16,"Chenmo Wang San");
Cmower wangyi = new Cmower(28,"Chenmo Wang Yi");
List<Cmower> list = new ArrayList<>();
list.add(wanger);
list.add(wangsan);
list.add(wangyi);
list.sort(new CmowerComparator());
for (Cmower c : list) {
System.out.println(c.getName());
}Napravio sam tri objekta s različitim age i name, i dodao ih u List. Zatim sam koristio sort() metodu List za sortiranje, pogledajmo rezultat.
Chenmo Wang San
Chenmo Wang Er
Chenmo Wang YiTo znači da je Chenmo Wang San mlađi od Chenmo Wang Er, pa je na prvom mestu; Chenmo Wang Yi je stariji od Chenmo Wang Er, pa je na trećem mestu. Potpuno se slaže sa našim očekivanjima.
Pogledajmo izvorni koda sort metode:
public void sort(Comparator<? super E> c) {
// čuva trenutnu vrednost modCount reda za detekciju nelegalne sort operacije
final int expectedModCount = modCount;
// poziva Arrays.sort za sortiranje elementData niza koristeći prosleđeni komparator c
Arrays.sort((E[]) elementData, 0, size, c);
// proverava da li je modCount izmenjen tokom operacije, ako jeste baca izuzetak konkurentne modifikacije
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
// povećava modCount vrednost, označavajući da je red izmenjen
modCount++;
}Možete videti da je parametar upravo Comparator interfejs, i koristi se generik Comparator<? super E> c.
03,Koji treba koristiti?
Kroz dva gornja primera možemo uporediti razlike između Comparable i Comparator:
- Ako klasa implementira Comparable interfejs, to znači da se objekti te klase mogu direktno porediti (sortirati), ali način poređenja (sortiranja) je samo jedan, vrlo jednostavan.
- Ako klasa želi da ostane u originalnom obliku, ali treba različite načine poređenja (sortiranja), možete napraviti prilagođeni komparator (implementirati Comparator interfejs).
- Comparable interfejs je u
java.langpaketu, aComparatorinterfejs je ujava.utilpaketu, nisu direktni braća, ali mogu se zvati rodjaka.
Dajmo neproporan primer. Hoću iz Luoyanga da idem u Peking da vidim Kineski zid, da osetim osećaj heroja, ili avionom ili brzim vozom; ali ako je Sun Wukong, okrene se i stigne. Koja je razlika između mene i Sun Wukonga?
Sun Wukong je sam implementirao Comparable interfejs (u njegovo vreme nije bilo aviona i brzih vozova, nije imao izbora), a ja mogu koristiti Comparator interfejs (moderni saobraćajni sredstva).
Dobro, o Comparable i Comparator ćemo za sada ovoliko. Ukratko, ako sortiranje objekata treba da bude zasnovano na prirodnom redosledu, odaberite Comparable, ako treba sortirati prema različitim osobinama objekta, odaberite Comparator.
