Összehasonlító, gyűjtemények válogatása - 1

– Szia Amigo!

– Szia, Bilaabo!

"Ma egy kicsi, de érdekes és hasznos témát vizsgálunk meg: a gyűjtemények válogatását."

– Rendezés? Hallottam erről valamit.

"Régen minden programozónak tudnia kellett rendezési algoritmusokat írni. Képes volt és meg is kellett írnia. De azok az idők elmúltak. Ma a saját rendezési kód megírása rossz formának számít, ugyanúgy, mint bármi más átírása, ami már megtörtént. kitalálták."

"A Java-ban (és más programozási nyelvekben) a rendezés már megvalósult.  Az Ön feladata, hogy megtanulja, hogyan kell megfelelően használni a már meglévőt. "

"RENDBEN."

"A Gyűjtemények segédosztály rendelkezik egy statikus rendezési módszerrel, amelyet a gyűjtemények – pontosabban a listák – rendezésére használnak. A Térképek és készletek elemeinek nincs sorrendje/indexük, így nincs mit rendezni."

– Igen, emlékszem. Egyszer ezt a módszert használtam a számlista rendezésére.

"Remek. De ez a módszer sokkal erősebb, mint amilyennek első pillantásra tűnik. Nemcsak számokat, hanem bármilyen objektumot is képes rendezni bármilyen kritérium alapján. Két interfész segíti ezt a módszert: Comparable és Comparator . "

"Néha objektumokat kell rendezni, nem számokat. Tegyük fel például, hogy van egy listája az emberekről, és szeretné őket életkor szerint rendezni. Ehhez a Comparable felülettel rendelkezünk."

"Először hadd mutassak egy példát, és akkor minden világosabb lesz:"

Példa
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;
}
}
Egy példa a használatára:
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);
}

"Az objektumok rendezéséhez először tudnia kell, hogyan kell összehasonlítani őket. Ehhez a Comparable-t használjuk. Az Összehasonlítható felület egy általános, ami azt jelenti, hogy típus argumentumot fogad el. Egyetlen általános metódusa van: a összehasonlítás(T o). Ez a metódus összehasonlítja az aktuális objektumot (this) és egy argumentumként átadott objektumot (o), vagyis ezt a metódust meg kell valósítanunk az osztályunkban, majd ezzel összehasonlítjuk az aktuális objektumot (this) az átadott objektummal. "

"És hogyan működik az összehasonlítás? Arra számítottam, hogy igaz vagy hamis ad vissza attól függően, hogy az átadott objektum nagyobb vagy kisebb."

"Itt a dolgok bonyolultabbak. Az Összehasonlítás metódus nem ad vissza igaz/hamis értéket. Ehelyett egy int értéket ad vissza. Ez valójában az egyszerűség kedvéért történik.

"Amikor egy számítógépnek meg kell határoznia, hogy egy szám nagyobb-e, mint a másik, egyszerűen kivonja a második számot az elsőből, majd megnézi az eredményt. Ha az eredmény 0, akkor a számok egyenlőek. Ha az eredmény kisebb, mint nulla , akkor a második szám nagyobb. És ha az eredmény nagyobb, mint nulla, akkor az első szám nagyobb."

"Ugyanez a logika érvényes itt is. A specifikáció szerint az összehasonlító metódusnak nullát kell visszaadnia, ha az összehasonlított objektumok egyenlőek. Ha az összehasonlítás metódus nullánál nagyobb számot ad vissza, akkor az objektumunk nagyobb, mint az átadott objektum. "Ha az összehasonlítás metódus nullánál kisebb számot ad vissza, akkor a „this” kisebb, mint az átadott objektum."

– Ez egy kicsit furcsa.

"Igen, de ha egyszerűen valamilyen numerikus tulajdonság alapján hasonlít össze objektumokat, akkor egyszerűen visszaadhatja a köztük lévő különbséget úgy, hogy kivonja az egyiket a másikból. Ugyanúgy, ahogy a fenti példában tette."

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

"Azt hiszem, mindent értek. De talán nem. De szinte mindent."

"Nagyszerű. Most nézzünk meg egy gyakorlatiasabb problémát. Tegyük fel, hogy írt egy remek webhelyet női ruházati termékek gyártására Kínában. Egy Woman osztályt használ ügyfeleinek leírására. Még egy weboldalt is készített egy táblázattal, ahol mindegyiket láthatja . De van egy probléma…”

"A Woman objektum nemcsak életkort tartalmaz, hanem egy csomó egyéb adatot is: keresztnév, vezetéknév, magasság, súly, gyerekek száma stb."

"A felhasználók táblázata sok oszlopot tartalmaz, és itt a kérdés: hogyan rendezi a felhasználókat a különböző szempontok szerint? Súly, életkor, vezetéknév szerint?"

"Hmm. Igen, gyakran látok táblázatokat, amelyek lehetővé teszik az oszlopok szerinti rendezést. Szóval, hogyan kell ezt csinálni?"

"Ehhez megvan a második felület, amiről ma beszélni akartam: a Comparator felület. Van egy összehasonlítási módszere is, de két argumentum kell hozzá, nem egy: int összehasonlítás(T o1, T o2). Így művek:"

Példa
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;
}
}
Egy példa a használatára:
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);
}

"A Comparator interfész nem rejti el az objektum-összehasonlítási logikát az összehasonlítandó objektumok osztályán belül. Ehelyett egy külön osztályban van megvalósítva."

"Tehát létrehozhatnék több osztályt, amelyek megvalósítják a Comparator felületet, és mindegyik különböző tulajdonságokat hasonlíthat össze? Az egyikben a súlyt, a másikban az életkort és a harmadikban a magasságot?"

– Igen, nagyon egyszerű és kényelmes.

"Csak a Collections.sort metódusnak hívjuk , második argumentumként egy objektumok listáját és egy másik speciális objektumot adunk át, amely megvalósítja a Comparator felületet, és megmondja, hogyan kell helyesen összehasonlítani az objektumpárokat a rendezési folyamat során."

"Hmm. Azt hiszem, mindent értek. Hadd próbáljam meg. Tegyük fel, hogy súly szerint kell rendeznem a felhasználókat. Valami ilyesmi lenne:"

Példa a felhasználók súly szerinti rendezésére:
Comparator<Woman> compareByWeight = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.weight - o2.weight;
}
};

Collections.sort(women, compareByWeight);

"Igen, pontosan."

"Remek. De mi van, ha fordított sorrendben akarok rendezni?"

"Gondolj bele. A válasz nagyon egyszerű!"

"Megvan! Így:"

Rendezés növekvő sorrendben:
return o1.weight - o2.weight;
Rendezés csökkenő sorrendben:
return o2.weight – o1.weight;

– Helyes. Jól sikerült.

"És ha vezetéknév szerint akarok rendezni? Hogyan rendezzem a karakterláncokat, Bilaabo?"

"A String osztály már megvalósítja az összehasonlítás metódusát. Csak meg kell hívnia:"

Példa a felhasználók név szerinti rendezésére:
Comparator<Woman> compareByName = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.name.compareTo(o2.name);
}
};

Collections.sort(women, compareByName);

"Ez egy nagyszerű lecke volt, Bilaabo. Köszönöm szépen."

– És köszönöm neked, barátom!