Ik heb gelezen over het sorteren van ArrayLists met behulp van een Comparator, maar in alle voorbeelden werd compareTo
gebruikt, wat volgens enig onderzoek een methode voor Strings is.
Ik wilde een ArrayList van aangepaste objecten sorteren op een van hun eigenschappen: een Datum object
(getStartDay()
). Normaal vergelijk ik ze door item1.getStartDate().before(item2.getStartDate())
dus ik vroeg me af of ik iets als het volgende zou kunnen schrijven:
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);
...
}
Omdat Date
Comparable
implementeert, heeft het een compareTo
methode, net als String
dat heeft.
Dus je aangepaste Comparator
zou er als volgt uit kunnen zien:
public class CustomComparator implements Comparator<MyObject> {
@Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
}
De vergelijk()
methode moet een int
teruggeven, dus je kunt niet direct een boolean
teruggeven zoals je toch al van plan was.
Je sorteercode zou ongeveer zijn zoals je schreef:
Collections.sort(Database.arrayList, new CustomComparator());
Een iets kortere manier om dit alles te schrijven, als je je comparator niet hoeft te hergebruiken, is om het als een inline anonieme klasse te schrijven:
Collections.sort(Database.arrayList, new Comparator<MyObject>() {
@Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
});
Je kunt het laatste voorbeeld nu in een kortere vorm schrijven door een lambda expressie te gebruiken voor de Comparator
:
Collections.sort(Database.arrayList,
(o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
En List
heeft een sort(Comparator)
methode, dus je kunt dit nog verder inkorten:
Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));
Dit is zo'n veelvoorkomend idioom dat er een ingebouwde methode is om een Comparator
te genereren voor een klasse met een Comparable
sleutel:
Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));
Dit zijn allemaal equivalente vormen.
Ja, dat kan. Er zijn twee mogelijkheden met het vergelijken van items, de Comparable
Beide interfaces laten verschillend gedrag toe. Comparable laat je toe om het object te laten handelen zoals je net Strings beschreven hebt (in feite, implementeert String Comparable). De tweede, Comparator, staat je toe om te doen wat je vraagt om te doen. Je zou het als volgt doen:
Collections.sort(myArrayList, new MyComparator());
Dat zal ervoor zorgen dat de Collections.sort methode jouw comparator gebruikt voor zijn sorteermechanisme. Als de objecten in de ArrayList vergelijkbaar implementeren, kun je in plaats daarvan iets als dit doen:
Collections.sort(myArrayList);
De klasse Collections bevat een aantal van deze nuttige, veelgebruikte hulpmiddelen.
uw aangepasteComparator klasse moet java.util.Comparator implementeren om gebruikt te kunnen worden. het moet ook vergelijk() EN vergelijk() overschrijven
compare() moet de vraag beantwoorden: Is object 1 kleiner dan, gelijk aan of groter dan object 2?
volledige docs: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html