Komparator, sortering av samlinger - 1

"Hei, Amigo!"

"Hei, Bilaabo!"

"I dag skal vi undersøke et lite, men interessant og nyttig emne: sortering av samlinger."

"Sortering? Jeg har hørt noe om det."

"For lenge siden måtte hver programmerer være i stand til å skrive sorteringsalgoritmer. Kunne og måtte skrive dem. Men de dagene er over. I dag anses det å skrive din egen sorteringskode som dårlig form, akkurat som å omskrive alt annet som allerede har blitt oppfunnet."

"I Java (og andre programmeringsspråk) er sortering allerede implementert.  Din oppgave er å lære hvordan du bruker det som allerede eksisterer på riktig måte. "

"OK."

" Hjelpeklassen Samlinger har en statisk sorteringsmetode som brukes til å sortere samlinger – eller mer presist, lister. Elementer i kart og sett har ingen rekkefølge/indeks, så det er ingenting å sortere."

"Ja, jeg husker. Jeg brukte denne metoden en gang for å sortere en liste med tall."

"Flott. Men denne metoden er mye kraftigere enn den ser ut ved første øyekast. Den kan sortere ikke bare tall, men også alle objekter, basert på hvilke som helst kriterier. To grensesnitt hjelper metoden med å gjøre dette: Comparable og Comparator . "

"Noen ganger må du sortere objekter, ikke tall. Anta for eksempel at du har en liste over personer, og du vil sortere dem etter alder. Vi har det sammenlignbare grensesnittet for dette."

"La meg først vise deg et eksempel, og så vil alt bli klarere:"

Eksempel
public class Woman implements Comparable<Woman>
{
public int age;

public Woman(int age) {
this.age = age;
}

public int compareTo(Woman o)
{
return this.age - o.age;
}
}
Et eksempel på hvordan det kan brukes:
public static void main(String[] args )
{
ArrayList<Woman> women = new ArrayList<Woman>();
women.add(new Woman(18));
women.add(new Woman(21));
women.add(new Woman(5));

Collections.sort(women);
}

"For å sortere objekter må du først vite hvordan du sammenligner dem. Til dette bruker vi Comparable. Comparable- grensesnittet er et generisk, som betyr at det godtar et type-argument. Det har bare én generisk metode: compareTo(T o). Denne metoden sammenligner det gjeldende objektet (dette) og et objekt sendt som et argument (o). Med andre ord må vi implementere denne metoden i klassen vår og deretter bruke den til å sammenligne det gjeldende objektet (dette) med det beståtte objektet. "

"Og hvordan fungerer compareTo? Jeg forventet at det ville returnere sant eller usant avhengig av om det passerte objektet var større eller mindre."

"Ting er vanskeligere her. CompareTo-metoden returnerer ikke true/false. I stedet returnerer den en int. Dette er faktisk gjort for enkelhets skyld.

"Når en datamaskin trenger å finne ut om ett tall er større enn et annet, trekker den ganske enkelt det andre tallet fra det første og ser deretter på resultatet. Hvis resultatet er 0, så er tallene like. Hvis resultatet er mindre enn null , da er det andre tallet større. Og hvis resultatet er større enn null, er det første tallet større."

"Den samme logikken gjelder her. I følge spesifikasjonen må compareTo-metoden returnere null hvis de sammenlignede objektene er like. Hvis compareTo-metoden returnerer et tall som er større enn null, er objektet vårt større enn det beståtte objektet. "Hvis compareTo-metoden metoden returnerer et tall mindre enn null, så er 'dette' mindre enn det beståtte objektet."

"Det er litt rart."

"Ja, men hvis du sammenligner objekter bare basert på en numerisk egenskap, kan du bare returnere forskjellen mellom dem ved å trekke den ene fra den andre. Akkurat slik det ble gjort i eksemplet ovenfor."

public int compareTo(Woman o)
{
return this.age - o.age;
}

"Jeg tror jeg forstår alt. Men kanskje ikke. Men nesten alt."

"Flott. La oss nå vurdere et mer praktisk problem. Tenk deg at du har skrevet en kul nettside for å lage dameklær i Kina. Du bruker en kvinneklasse for å beskrive kundene dine. Du har til og med laget en nettside med en tabell der du kan se dem alle . Men det er et problem..."

"Ditt Woman-objekt inneholder ikke bare en alder, men også en hel haug med andre data: fornavn, etternavn, høyde, vekt, antall barn, etc."

"Brukertabellen har mange kolonner, og her er spørsmålet: hvordan sorterer du brukerne dine etter de ulike kriteriene? Etter vekt, etter alder, etter etternavn?"

"Hmm. Ja, jeg ser ofte tabeller som lar deg sortere etter kolonne. Så hvordan gjør du det?"

"For dette har vi det andre grensesnittet jeg ønsket å fortelle deg om i dag: Comparator-grensesnittet. Det har også en sammenligningsmetode, men det krever to argumenter, ikke ett: int compare(T o1, T o2). Slik ser det ut. virker:"

Eksempel
public class Woman
{
public int age;
public int childrenCount;
public int weight;
public int height;
public String name;

public Woman(int age) {
this.age = age;
}
}
Et eksempel på hvordan det kan brukes:
public static void main(String[] args )
{
ArrayList<Woman> women = new ArrayList<Woman>();
women.add(new Woman(18));
women.add(new Woman(21));
women.add(new Woman(5));

Comparator<Woman> compareByHeight = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.height - o2.height;
}
};

Collections.sort(women, compareByHeight);
}

"Comparator-grensesnittet skjuler ikke objektsammenligningslogikken inne i klassen til objektene som sammenlignes. I stedet implementeres den i en egen klasse."

"Så jeg kunne lage flere klasser som implementerer Comparator-grensesnittet, og få hver av dem til å sammenligne forskjellige egenskaper? Vekt i en, alder i en annen og høyde i en tredje?"

"Ja, det er veldig enkelt og praktisk."

"Vi kaller bare Collections.sort- metoden, og sender en liste over objekter og et annet spesialobjekt som det andre argumentet, som implementerer Comparator- grensesnittet og forteller deg hvordan du korrekt sammenligner par av objekter i sorteringsprosessen."

"Hmm. Jeg tror jeg forstår alt. La meg prøve det. La oss si at jeg må sortere brukere etter vekt. Det ville vært noe sånt som dette:"

Eksempel på sortering av brukere etter vekt:
Comparator<Woman> compareByWeight = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.weight - o2.weight;
}
};

Collections.sort(women, compareByWeight);

"Ja nøyaktig."

"Flott. Men hva om jeg vil sortere i omvendt rekkefølge?"

"Tenk deg om. Svaret er veldig enkelt!"

"Jeg har det! Slik:"

Sortering i stigende rekkefølge:
return o1.weight - o2.weight;
Sortering i synkende rekkefølge:
return o2.weight – o1.weight;

"Riktig. Godt gjort."

"Og hvis jeg vil sortere etter etternavn? Hvordan sorterer jeg strenger, Bilaabo?"

"String-klassen implementerer allerede compareTo-metoden. Du trenger bare å kalle den:"

Eksempel på sortering av brukere etter navn:
Comparator<Woman> compareByName = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.name.compareTo(o2.name);
}
};

Collections.sort(women, compareByName);

"Det var en flott leksjon, Bilaabo. Tusen takk."

"Og takk til deg, min venn!"