Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Completed the Comparable part. Halfway on Comparator
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
languagejava
titleOlympicCountry
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
languagejava
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. 

 

 

SidetypeFerdig
Teori50