Excerpt |
---|
Denne siden forklarer hvordan grensesnittene java.util.Comparable og java.util.Comparator bidrar til sortering i Java. |
Comparable og Comparator er interfaces som lar deg bestemme hvordan dine egne objekter skal rangeres i forhold til hverandre. Dette kommer spesielt godt til nytte når man bruker Collection-rammeverket, spesielt metoden Collections.sort.
Comparable<T>
Comparable er det vanlig at klassen din implementerer. Den krever at du har definert metoden .compareTo(T), hvor T er klassen som skal sammenlignes. CompareTo metoden skal returnere et Negativt tall hvis "this" er mindre enn det andre instanse. 0 hvis de er like, og et positivt tall dersom "this" er større enn det andre instanset.
Sett at du har en klasse som definerer et Land som deltar i OL. Klassen har felter for antall gull, sølv og bronsje. For at du skal kunne avgjøre hvilket land som kommer høyest opp på medalje rangeringen trenger man en metode for å avgjøre dette.
Code Block | ||||
---|---|---|---|---|
| ||||
public class OlympicCountry implements Comparable<OlympicCountry> { //inne i klammene defineres hvilken klasse som skal sammenlignes i compareTo-metoden
private String name;
private int goldMedals;
private int silverMedals;
private int bronzeMedals;
public OlympicCountry(String name, int goldMedals, int silverMedals, int bronzeMedals){
this.name = name;
this.goldMedals = goldMedals;
this.silverMedals = silverMedals;
this.bronzeMedals = bronzeMedals;
}
public int getGoldMedals() {
return goldMedals;
}
public int getSilverMedals() {
return silverMedals;
}
public int getBronzeMedals() {
return bronzeMedals;
}
@Override
public String toString(){
return name + "\t: g: "+ goldMedals+", s: " + silverMedals + ", b: " + bronzeMedals;
}
//@Override
public int compareTo(OlympicCountry o) {
if(this.getGoldMedals() != o.getGoldMedals()) // hvis guld er ulike returnerer deres forskjell
return this.getGoldMedals() - o.getGoldMedals();
else if(this.getSilverMedals() != o.getSilverMedals())//hvis sølv er ulike returneres deres forskjell
return this.getSilverMedals() - o.getSilverMedals();
else
return this.getBronzeMedals() - o.getBronzeMedals(); // hvis den er kommet hit er guld og sølv like, da returnerer den bronsje forskjellen. Om den også er lik returneres 0, som indikerer at instansene er like gode.
}
public static void main(String[] args) {
OlympicCountry china = new OlympicCountry("China", 2, 4, 1);
OlympicCountry japan = new OlympicCountry("Japan", 2, 5, 1);
System.out.println(china.compareTo(Japan)); // printer ut -1. Dette betyr at Japan er bedre enn Kina.
} |
Så hvorfor er dette så fantastisk. Jo, som nevnt over så kan man bruke det i forbindelse med sortering. Collections.sort() krever bare at du sender med en liste som arver fra Collections og at denne listen inneholder et objekt som implementerer Comparable-interfacet.
Her ser dere en ny main-metode som bruker den allerede definerte klassen over OlympicCountry
Code Block | ||
---|---|---|
| ||
public static void main(String[] args) {
ArrayList<OlympicCountry> countries = new ArrayList<OlympicCountry>();
countries.add(new OlympicCountry("Norway", 5, 3, 7));
countries.add(new OlympicCountry("Sweden", 2, 9, 3));
countries.add(new OlympicCountry("Finland", 9, 2, 1));
countries.add(new OlympicCountry("Russia", 2, 9, 12));
countries.add(new OlympicCountry("Denmark", 7, 1, 6));
countries.add(new OlympicCountry("England", 5, 2, 10));
countries.add(new OlympicCountry("Canada", 5, 0, 4));
countries.add(new OlympicCountry("USA", 9, 2, 2));
print(countries);
/*
Printer ut:
Norway : g: 5, s: 3, b: 7
Sweden : g: 2, s: 9, b: 3
Finland : g: 9, s: 2, b: 1
Russia : g: 2, s: 9, b: 12
Denmark : g: 7, s: 1, b: 6
England : g: 5, s: 2, b: 10
Canada : g: 5, s: 0, b: 4
USA : g: 9, s: 2, b: 2
Altså usortert, men ettersom klassen vår implementerer Comparable kan vi nå sortere instansene slik vi ønsker.
*/
Collections.sort(countries);
print(countries);
/*
Sweden : g: 2, s: 9, b: 3
Russia : g: 2, s: 9, b: 12
Canada : g: 5, s: 0, b: 4
England : g: 5, s: 2, b: 10
Norway : g: 5, s: 3, b: 7
Denmark : g: 7, s: 1, b: 6
Finland : g: 9, s: 2, b: 1
USA : g: 9, s: 2, b: 2
Nå kan dere se at listen er sortert, men den er fortsatt ikke slik vi ønsker den, selvom compartTo klassen er helt rett. Les neste avsnitt for løsningen.
}
//for oversiktelig utskrift av ArrayListen
public static void print(ArrayList<OlympicCountry> countries){
for (OlympicCountry country : countries) {
System.out.println(country);
}
} |
Comparator
Problemet over er at sorteringsalgoritmen automatisk sorterer i stigende rekkefølge. En enkel fiks ville vært å bytte om på objektene i compareTo()-metoden, men dette ville vært feil ettersom Comparable skal gjenspeile klassens naturlige ordning, og kan derfor ikke tilpasses for et spesielt problem. Løsningen er å bruke en Comparator. I motsetning til Comparable , så er Comparator tiltenkt å implementeres av en annen klasse enn den som skal sorteres. Den kan da også ha friere regler på utfallet av sammenligninger. For å bruke en comparator sendes den enkelt med som et andre argument til Collections.sort() kallet.
Sidetype | Ferdig |
---|---|
Teori | 50 |