Útmutató a Java 8 Comparatorhoz. Összehasonlítás ()

1. Áttekintés

A Java 8 számos fejlesztést vezetett be a Összehasonlító interfész, beleértve egy maroknyi statikus funkciót, amelyek nagy hasznát veszik a gyűjtemények rendezési sorrendjének kidolgozásakor.

A Java 8 lambdas hatékonyan kihasználható a Összehasonlító interfész is. A lambdas és a Összehasonlító itt található, valamint egy krónika a Összehasonlító itt található.

Ebben az oktatóanyagban meg fogjuk vizsgálni a Összehasonlító felület a Java 8-ban.

2. Az első lépések

2.1. Mintabab osztály

A cikk példáihoz hozzunk létre egy Munkavállaló babot, és mezőit használja összehasonlítási és rendezési célokra:

public class Alkalmazott {String név; int kor; kettős fizetés; hosszú mobil; // kivitelezők, szerelők és beállítók}

2.2. Tesztelési adataink

Hozzunk létre egy alkalmazotti tömböt is, amelyet a cikkünkben különböző tesztesetekben tárolunk a típusunk eredményei számára:

alkalmazottak = új alkalmazott [] {...};

Az elemek kezdeti rendezése alkalmazottak lesz:

[Alkalmazott (név = John, életkor = 25, fizetés = 3000,0, mobil = 9922001), Alkalmazott (név = Ász, életkor = 22, fizetés = 2000,0, mobil = 5924001), Alkalmazott (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401)]

A cikkben a fentiek szerint válogatunk Munkavállaló tömb különböző funkciók használatával.

A teszt állításokhoz előre rendezett tömböket használunk, amelyeket összehasonlítunk rendezési eredményeinkkel (azaz alkalmazottak tömb) különböző forgatókönyvekhez.

Nyilatkozjuk néhány ilyen tömböt:

@A nyilvános void előtt initData () {sortedEmployeesByName = new Employee [] {...}; sortedEmployeesByNameDesc = új alkalmazott [] {...}; sortedEmployeesByAge = új alkalmazott [] {...}; // ...}

Mint mindig, a teljes kódot bátran olvassa el a GitHub linkünkön.

3. Használata Összehasonlító.összehasonlítás

Ez a szakasz a Összehasonlító.összehasonlítás statikus függvény.

3.1. Kulcsválasztó variáns

A Összehasonlító.összehasonlítás a statikus függvény elfogad egy rendezési kulcsot Funkció és visszaadja a Összehasonlító a típushoz, amely a rendezési kulcsot tartalmazza:

statikus  Összehasonlító összehasonlítás (Function keyExtractor)

Ahhoz, hogy ezt működés közben lássuk, használjuk a név mező ben Munkavállaló rendezési kulcsként, és adja át a metódus hivatkozását típusú argumentumként Funkció. A Összehasonlító ugyanabból visszaküldött rendezésre szolgál:

@Test public void whenComparing_thenSortedByName () {Comparator workerNameComparator = Comparator.comparing (Employee :: getName); Arrays.sort (alkalmazottak, alkalmazottNévKomparátor); assertTrue (tömbök.egyenlő (alkalmazottak, sortedEmployeesByName)); }

Mint láthatja, a alkalmazottak tömb értékek név szerint vannak rendezve a rendezés eredményeként:

[Munkavállaló (név = Ász, életkor = 22, fizetés = 2000,0, mobil = 5924001), Munkavállaló (név = János, életkor = 25, fizetés = 3000,0, mobil = 9922001), Munkavállaló (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401)] 

3.2. Kulcsválasztó és Összehasonlító Változat

Van még egy lehetőség, amely megkönnyíti a rendezési kulcs természetes sorrendjének felülírását az Összehasonlító amely egyéni rendezést hoz létre a rendezési kulcshoz:

statikus összehasonlító összehasonlítása (Function keyExtractor, Comparator keyComparator)

Módosítsuk a fenti tesztet, felülírva a rendezés természetes sorrendjét név mezőt a Összehasonlító a nevek csökkenő sorrendbe rendezéséhez a második argumentumként Összehasonlító.összehasonlítás:

@Test public void whenComparingWithComparator_thenSortedByNameDesc () {Comparator workerNameComparator = Comparator.comparing (Employee :: getName, (s1, s2) -> {return s2.compareTo (s1; Arrays.sort (alkalmazottak, alkalmazottNévKomparátor); assertTrue (Tömbök.egyenlő (alkalmazottak, sortedEmployeesByNameDesc)); }

Amint láthatja, az eredményeket csökkenő sorrendben rendezik név:

[Munkavállaló (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401), Munkavállaló (név = János, életkor = 25, fizetés = 3000,0, mobil = 9922001), Munkavállaló (név = Ász, életkor = 22, fizetés = 2000,0, mobil = 5924001)]

3.3. Használata Összehasonlító.fordítva

Amikor létezőre hívják Összehasonlító, a példány metódus Összehasonlító.fordítva egy újat ad vissza Összehasonlító ez megfordítja az eredeti rendezési sorrendjét.

Használjuk a Összehasonlító hogy az alkalmazottakat rendezi név és fordított úgy, hogy az alkalmazottak a név:

@Test public void whenReversed_thenSortedByNameDesc () {Comparator workerNameComparator = Comparator.comparing (Employee :: getName); Comparator workerNameComparatorReversed = alkalmazottNévComparator.reversed (); Arrays.sort (alkalmazottak, alkalmazottNévKomparátorReversed); assertTrue (tömbök.egyenlő (alkalmazottak, sortedEmployeesByNameDesc)); }

Az eredményeket csökkenő sorrendben rendezik név:

[Munkavállaló (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401), Munkavállaló (név = János, életkor = 25, fizetés = 3000,0, mobil = 9922001), Munkavállaló (név = Ász, életkor = 22, fizetés = 2000,0, mobil = 5924001)]

3.4. Használata Comparator.comparingInt

Van egy funkció is Comparator.comparingInt amely ugyanazt teszi, mint Összehasonlító.összehasonlítás, de csak erre van szükség int válogatók. Próbáljuk ki ezt egy példával, ahol megrendeljük alkalmazottak által kor:

@Test public void whenComparingInt_thenSortedByAge () {Comparator workerAgeComparator = Comparator.comparingInt (Employee :: getAge); Arrays.sort (alkalmazottak, alkalmazottAgeComparator); assertTrue (tömbök.egyenlő (alkalmazottak, sortedEmployeesByAge)); }

Lássuk, hogyan alkalmazottak a tömb értékeket a rendezés után rendezik:

[Munkavállaló (név = Ász, életkor = 22, fizetés = 2000,0, mobil = 5924001), Munkavállaló (név = János, életkor = 25, fizetés = 3000,0, mobil = 9922001), Munkavállaló (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401)]

3.5. Használata Comparator.comparingLong

Hasonló, mint amit tettünk int kulcsokat, nézzünk meg egy példát a Comparator.comparingLong hogy fontoljon egy típusú rendezési kulcsot hosszú megrendelésével a alkalmazottak tömb a Mobil terület:

@Test public void whenComparingLong_thenSortedByMobile () {Comparator workerMobileComparator = Comparator.comparingLong (Employee :: getMobile); Tömbök.sort (alkalmazottak, alkalmazottMobileComparator); assertTrue (Tömbök.egyenlő (alkalmazottak, sortedEmployeesByMobile)); }

Lássuk, hogyan alkalmazottak a tömb értékeket a rendezés után rendezi Mobil mint kulcs:

[Munkavállaló (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401), Munkavállaló (név = Ász, életkor = 22, fizetés = 2000,0, mobil = 5924001), Munkavállaló (név = János, életkor = 25, fizetés = 3000,0, mobil = 9922001)]

3.6. Használata Comparator.comparingDouble

Ismét hasonló ahhoz, amit tettünk int és hosszú kulcsokat, nézzünk meg egy példát a Comparator.comparingDouble hogy fontoljon egy típusú rendezési kulcsot kettős megrendelésével a alkalmazottak tömb a fizetés terület:

@Test public void whenComparingDouble_thenSortedBySalary () {Comparator workerSalaryComparator = Comparator.comparingDouble (Employee :: getSalary); Tömbök.sort (alkalmazottak, alkalmazottSalaryComparator); assertTrue (tömbök.egyenlő (alkalmazottak, sortedEmployeesBySalary)); }

Lássuk, hogyan alkalmazottak a tömb értékeket a rendezés után rendezi fizetés mint rendezési kulcs:

[Munkavállaló (név = Ász, életkor = 22, fizetés = 2000,0, mobil = 5924001), Munkavállaló (név = János, életkor = 25, fizetés = 3000,0, mobil = 9922001), Munkavállaló (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401)]

4. Figyelembe véve a természetes rendet Összehasonlító

A természetes rendet a. Viselkedése határozza meg Hasonló interfész megvalósítása. További információ a különbségről Összehasonlító és felhasználása Hasonló felület megtalálható ebben a cikkben.

Tegyük végre Hasonló miénkben Munkavállaló osztály, hogy kipróbálhassuk a naturalRendelés és fordított sorrendben funkciói Összehasonlító felület:

public class Employee implement Comparable {// ... @Orride public int CompareTo (Employee argEmployee) {return name.compareTo (argEmployee.getName ()); }}

4.1. A természetes rend használata

A naturalRendelés függvény a Összehasonlító az aláírásban említett visszatérési típus esetében:

statikus  Természetes összehasonlítóRendelés ()

A fenti logika alapján az alkalmazottak összehasonlítása az alapján név mezőben használjuk ezt a függvényt a Összehasonlító amely rendezi a alkalmazottak tömb természetes sorrendben:

@Test public void whenNaturalOrder_thenSortedByName () {Comparator workerNameComparator = Összehasonlító. naturalRendelés (); Arrays.sort (alkalmazottak, alkalmazottNévKomparátor); assertTrue (tömbök.egyenlő (alkalmazottak, sortedEmployeesByName)); }

Lássuk, hogyan alkalmazottak a tömb értékeket a rendezés után rendezik:

[Munkavállaló (név = Ász, életkor = 22, fizetés = 2000,0, mobil = 5924001), Munkavállaló (név = János, életkor = 25, fizetés = 3000,0, mobil = 9922001), Munkavállaló (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401)]

4.2. A fordított természetes rend használata

Hasonló naturalRendelés, használjuk a fordított sorrendben módszer a Összehasonlító amelynek fordított sorrendje lesz alkalmazottak a naturalRendelés példa:

@Test public void whenReverseOrder_thenSortedByNameDesc () {Comparator workerNameComparator = Összehasonlító. fordított sorrendben(); Arrays.sort (alkalmazottak, alkalmazottNévKomparátor); assertTrue (tömbök.egyenlő (alkalmazottak, sortedEmployeesByNameDesc)); }

Lássuk, hogyan alkalmazottak a tömb értékeket a rendezés után rendezik:

[Munkavállaló (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401), Munkavállaló (név = János, életkor = 25, fizetés = 3000,0, mobil = 9922001), Munkavállaló (név = Ász, életkor = 22, fizetés = 2000,0, mobil = 5924001)]

5. A nullértékek figyelembevétele az összehasonlítóban

Ez a szakasz a funkciókat ismerteti nullsElőször és nullsLast, amelyek figyelembe veszik nulla értékek a sorrendben és a nulla értékek a sorrend elején vagy végén.

5.1. Figyelembe véve a Null First-t

Véletlenszerűen szúrjuk be nulla értékek ben alkalmazottak sor:

[Alkalmazott (név = John, életkor = 25, fizetés = 3000,0, mobil = 9922001), null, alkalmazott (név = ász, életkor = 22, fizetés = 2000,0, mobil = 5924001), null, alkalmazott (név = Keith, életkor) = 35, fizetés = 4000,0, mobil = 3924401)]

A nullsElőször függvény visszaadja a Összehasonlító hogy mindent megtart nullák a sorrend elején:

@Test public void whenNullsFirst_thenSortedByNameWithNullsFirst () {Comparator workerNameComparator = Comparator.comparing (Employee :: getName); Összehasonlító alkalmazottNévComparator_nullFirst = Összehasonlító.nullsFirst (alkalmazottNévKomparátor); Arrays.sort (alkalmazottakArrayWithNulls, alkalmazottNévKomparátor_nullFirst); assertTrue (tömbök.egyenlő (alkalmazottakArrayWithNulls, sortedEmployeesArray_WithNullsFirst)); }

Lássuk, hogyan alkalmazottak a tömb értékeket a rendezés után rendezik:

[null, null, Alkalmazott (név = Ász, életkor = 22, fizetés = 2000,0, mobil = 5924001), Alkalmazott (név = János, életkor = 25, fizetés = 3000,0, mobil = 9922001), Alkalmazott (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401)]

5.2. Figyelembe véve Null Last

A nullsLast függvény a Összehasonlító hogy mindent megtart nullák a sorrend végén:

@Test public void whenNullsLast_thenSortedByNameWithNullsLast () {Comparator workerNameComparator = Comparator.comparing (Employee :: getName); Comparator workerNameComparator_nullLast = Összehasonlító.nullsLast (alkalmazottNévKomparátor); Arrays.sort (alkalmazottakArrayWithNulls, alkalmazottNévKomparátor_nullLast); assertTrue (tömbök. egyenlő (alkalmazottakArrayWithNulls, sortedEmployeesArray_WithNullsLast)); }

Lássuk, hogyan alkalmazottak a tömb értékeket a rendezés után rendezik:

[Munkavállaló (név = Ász, életkor = 22, fizetés = 2000,0, mobil = 5924001), Munkavállaló (név = János, életkor = 25, fizetés = 3000,0, mobil = 9922001), Munkavállaló (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401), null, null]

6. Használata Összehasonlító.akkor Összehasonlítás

A akkorHasonlítás funkció segítségével beállíthatja az értékek lexikográfiai sorrendjét úgy, hogy több rendezési kulcsot biztosít egy adott sorrendben.

Vegyünk egy másik tömböt Munkavállaló osztály:

someMoreEmployees = new Employee [] {...};

Vegye figyelembe a fenti tömb következő elemeit:

[Munkavállaló (név = Jake, életkor = 25, fizetés = 3000,0, mobil = 9922001), Munkavállaló (név = Jake, életkor = 22, fizetés = 2000,0, mobil = 5924001), Munkavállaló (név = Ász, életkor = 22, fizetés = 3000,0, mobil = 6423001), alkalmazott (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401)]

Írjuk az összehasonlítások sorozatát kor majd a név és nézze meg ennek a tömbnek a sorrendjét:

@Test public void whenThenComparing_thenSortedByAgeName () {Comparator worker_Age_Name_Comparator = Comparator.comparing (Employee :: getAge) .thenComparing (Employee :: getName); Tömbök.sort (someMoreEmployees, worker_Age_Name_Comparator); assertTrue (tömbök.egyenlő (néhányTöbbEmployees, sortedEmployeesByAgeName)); }

A megrendelést itt végzi el kor, és az azonos értékekkel kor, a megrendelést a név. Figyeljük meg ezt a válogatás után kapott sorrendben:

[Munkavállaló (név = Ász, életkor = 22, fizetés = 3000,0, mobil = 6423001), Munkavállaló (név = Jake, életkor = 22, fizetés = 2000,0, mobil = 5924001), Munkavállaló (név = Jake, életkor = 25, fizetés = 3000,0, mobil = 9922001), alkalmazott (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401)]

Használjuk a másik verzióját akkorHasonlítás vagyis akkorHasonlításInt, a lexikográfiai sorrend megváltoztatásával név utána kor:

@Test public void whenThenComparing_thenSortedByNameAge () {Comparator worker_Name_Age_Comparator = Comparator.comparing (Employee :: getName) .thenComparingInt (Employee :: getAge); Tömbök.sort (someMoreEmployees, worker_Name_Age_Comparator); assertTrue (Tömbök.egyenlő (néhányTöbbEmployees, sortedEmployeesByNameAge)); }

Lássuk, hogyan alkalmazottak a tömb értékeket a rendezés után rendezik:

[Alkalmazott (név = Ász, életkor = 22, fizetés = 3000,0, mobil = 6423001), Alkalmazott (név = Jake, életkor = 22, fizetés = 2000,0, mobil = 5924001), Alkalmazott (név = Jake, életkor = 25, fizetés = 3000,0, mobil = 9922001), alkalmazott (név = Keith, életkor = 35, fizetés = 4000,0, mobil = 3924401)]

Hasonlóképpen vannak funkciók akkorHosszúság összehasonlítása és akkorA kettős összehasonlítása használatra hosszú és kettős válogató kulcsok.

7. Következtetés

Ez a cikk útmutató a Java 8-ban bevezetett számos funkcióhoz Összehasonlító felület.

Szokás szerint a forráskód megtalálható a Githubon.