Comparator, collecties sorteren - 1

"Hallo Amigo!"

"Hallo Bilaabo!"

"Vandaag zullen we een klein, maar interessant en nuttig onderwerp onderzoeken: collecties sorteren."

"Sorteren? Daar heb ik iets over gehoord."

"Lang geleden moest elke programmeur sorteeralgoritmen kunnen schrijven. Kon en moest ze schrijven. Maar die tijd is voorbij. Tegenwoordig wordt het schrijven van je eigen sorteercode als een slechte vorm beschouwd, net als het herschrijven van al het andere dat al is geschreven." uitgevonden."

"In Java (en andere programmeertalen) is sorteren al geïmplementeerd.  Jouw taak is om te leren hoe je op de juiste manier gebruik kunt maken van wat al bestaat. "

"OK."

"De hulpklasse Collections heeft een statische sorteermethode die wordt gebruikt om collecties te sorteren, of beter gezegd, lijsten. Elementen in Maps en Sets hebben geen volgorde/index, dus er valt niets te sorteren."

'Ja, dat weet ik nog. Ik heb deze methode een keer gebruikt om een ​​lijst met getallen te sorteren.'

"Geweldig. Maar deze methode is veel krachtiger dan het op het eerste gezicht lijkt. Het kan niet alleen getallen sorteren, maar ook alle objecten, op basis van elk criterium. Twee interfaces helpen de methode hierbij: Vergelijkbaar en Vergelijkend . "

"Soms moet je objecten sorteren, geen nummers. Stel dat je een lijst met mensen hebt en je wilt ze sorteren op leeftijd. We hebben hiervoor de Comparable-interface. "

"Ik zal je eerst een voorbeeld laten zien, dan wordt alles duidelijker:"

Voorbeeld
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;
}
}
Een voorbeeld van hoe het kan worden gebruikt:
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);
}

"Om objecten te sorteren, moet je eerst weten hoe je ze moet vergelijken. Hiervoor gebruiken we Comparable. De Comparable- interface is generiek, wat betekent dat het een type-argument accepteert. Het heeft slechts één generieke methode: CompareTo(T o). Deze methode vergelijkt het huidige object (dit) en een object dat als argument is doorgegeven (o).Met andere woorden, we moeten deze methode in onze klasse implementeren en deze vervolgens gebruiken om het huidige object (dit) te vergelijken met het doorgegeven object. "

"En hoe werkt CompareTo? Ik verwachtte dat het waar of onwaar zou zijn, afhankelijk van of het gepasseerde object groter of kleiner was."

"De dingen zijn hier lastiger. De CompareTo-methode retourneert niet waar/onwaar. In plaats daarvan retourneert het een int. Dit wordt eigenlijk gedaan voor de eenvoud.

"Wanneer een computer moet bepalen of het ene getal groter is dan het andere, trekt hij eenvoudigweg het tweede getal van het eerste af en kijkt dan naar het resultaat. Als het resultaat 0 is, zijn de getallen gelijk. Als het resultaat kleiner is dan nul , dan is het tweede getal groter. En als het resultaat groter is dan nul, dan is het eerste getal groter."

"Dezelfde logica is hier van toepassing. Volgens de specificatie moet de methode CompareTo nul retourneren als de vergeleken objecten gelijk zijn. Als de methode CompareTo een getal retourneert dat groter is dan nul, dan is ons object groter dan het doorgegeven object. "Als de CompareTo methode retourneert een getal kleiner dan nul, dan is 'dit' kleiner dan het doorgegeven object."

"Dat is een beetje raar."

"Ja, maar als je objecten vergelijkt op basis van een numerieke eigenschap, dan kun je het verschil ertussen gewoon teruggeven door de ene van de andere af te trekken. Precies zoals in het bovenstaande voorbeeld."

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

'Ik denk dat ik alles begrijp. Maar misschien ook niet. Maar bijna alles.'

"Geweldig. Laten we nu eens kijken naar een meer praktisch probleem. Stel dat je een coole website hebt geschreven voor het maken van dameskleding in China. Je gebruikt een Woman-klasse om je klanten te beschrijven. Je hebt zelfs een webpagina gemaakt met een tabel waar je ze allemaal kunt zien Maar er is een probleem..."

"Je Woman-object bevat niet alleen een leeftijd, maar ook een heleboel andere gegevens: voornaam, achternaam, lengte, gewicht, aantal kinderen, enz."

"De tabel met gebruikers heeft veel kolommen, en hier is de vraag: hoe sorteert u uw gebruikers op basis van de verschillende criteria? Op gewicht, op leeftijd, op achternaam?"

"Hmm. Ja, ik zie vaak tabellen waarmee je op kolom kunt sorteren. Hoe doe je dat?"

"Hiervoor hebben we de tweede interface waarover ik je vandaag wilde vertellen: de Comparator-interface. Het heeft ook een vergelijkingsmethode, maar er zijn twee argumenten nodig, niet één: int vergelijk (T o1, T o2). Zo werkt het werken:"

Voorbeeld
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;
}
}
Een voorbeeld van hoe het kan worden gebruikt:
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);
}

"De Comparator-interface verbergt de objectvergelijkingslogica niet binnen de klasse van de objecten die worden vergeleken. In plaats daarvan wordt deze geïmplementeerd in een aparte klasse."

"Dus ik zou verschillende klassen kunnen maken die de Comparator-interface implementeren, en elk van hen verschillende eigenschappen laten vergelijken? Gewicht in de ene, leeftijd in een andere en lengte in een derde?"

"Ja, het is heel eenvoudig en handig."

"We noemen gewoon de Collections.sort- methode, waarbij we een lijst met objecten en een ander speciaal object doorgeven als het tweede argument, dat de Comparator- interface implementeert en je vertelt hoe je objectparen correct kunt vergelijken in het sorteerproces."

"Hmm. Ik denk dat ik alles begrijp. Laat me het eens proberen. Laten we zeggen dat ik gebruikers op gewicht moet sorteren. Het zou ongeveer zo zijn:"

Voorbeeld van het sorteren van gebruikers op gewicht:
Comparator<Woman> compareByWeight = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.weight - o2.weight;
}
};

Collections.sort(women, compareByWeight);

"Ja precies."

"Geweldig. Maar wat als ik in omgekeerde volgorde wil sorteren?"

"Denk er eens over na. Het antwoord is heel simpel!"

"Ik heb het! Zoals dit:"

Sorteren in oplopende volgorde:
return o1.weight - o2.weight;
Aflopend sorteren:
return o2.weight – o1.weight;

"Juist. Goed gedaan."

'En als ik op achternaam wil sorteren? Hoe sorteer ik strings, Bilaabo?'

"De klasse String implementeert de methode CompareTo al. U hoeft deze alleen maar aan te roepen:"

Voorbeeld van het sorteren van gebruikers op naam:
Comparator<Woman> compareByName = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.name.compareTo(o2.name);
}
};

Collections.sort(women, compareByName);

'Dat was een geweldige les, Bilaabo. Heel erg bedankt.'

"En bedankt aan jou, mijn vriend!"