Prebral sem o razvrščanju ArrayLists z uporabo komparatorja, vendar so v vseh primerih ljudje uporabili compareTo
, ki je po nekaterih raziskavah metoda za niza.
Želel sem razvrstiti ArrayList predmetov po meri po eni od njihovih lastnosti: predmet Date
(getStartDay()
). Običajno jih primerjam po načelu pomenka1.getStartDate().before(item2.getStartDate())
, zato me je zanimalo, ali lahko napišem kaj takega:
public class CustomComparator {
public boolean compare(Object object1, Object object2) {
return object1.getStartDate().before(object2.getStartDate());
}
}
public class RandomName {
...
Collections.sort(Database.arrayList, new CustomComparator);
...
}
Ker Date
implementira Comparable
, ima metodo compareTo
tako kot String
.
Tako bi lahko vaš lastni Comparator
izgledal takole:
public class CustomComparator implements Comparator<MyObject> {
@Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
}
Metoda compare()
mora vrniti int
, zato ne morete neposredno vrniti boolean
, kot ste nameravali.
Vaša koda za razvrščanje bi bila približno takšna, kot ste jo napisali:
Collections.sort(Database.arrayList, new CustomComparator());
Če vam primerjalnika ni treba ponovno uporabiti, lahko vse to zapišete na nekoliko krajši način, in sicer tako, da ga zapišete kot anonimni razred v vrstici:
Collections.sort(Database.arrayList, new Comparator<MyObject>() {
@Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
});
Zadnji primer lahko zdaj zapišete v krajši obliki z uporabo izraza lambda za Comparator
:
Collections.sort(Database.arrayList,
(o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
In List
ima metodo sort(Comparator)
, tako da lahko to še skrajšate:
Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
To je tako pogost idiom, da obstaja vgrajena metoda za ustvarjanje Comparatorja
za razred s ključem Comparable
:
Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));
Vse te oblike so enakovredne.
Da, lahko. Pri primerjanju elementov obstajata dve možnosti: vmesnik Comparable
Oba vmesnika omogočata različno obnašanje. Primerjalnik omogoča, da se predmet obnaša tako, kot ste pravkar opisali nizov (v resnici niz implementira primerjalnik). Drugi vmesnik, Comparator, pa vam omogoča, da naredite to, kar ste zahtevali. To bi storili takole:
Collections.sort(myArrayList, new MyComparator());
To bo povzročilo, da bo metoda Collections.sort uporabila vaš komparator za mehanizem razvrščanja. Če so predmeti v seznamu ArrayList primerljivi, lahko namesto tega naredite nekaj takega:
Collections.sort(myArrayList);
Razred Collections vsebuje številna uporabna in pogosta orodja.
vaš razred po meriComparator mora implementirati java.util.Comparator, da se lahko uporablja. prav tako mora prekrivati compare() IN equals()
compare() mora odgovoriti na vprašanje: Ali je objekt 1 manjši, enak ali večji od objekta 2?
Celotna dokumentacija: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html