Vodič za usporedbu Java 8 usporedbe ()

1. Pregled

Java 8 je uveo nekoliko poboljšanja u Usporednik sučelje, uključujući pregršt statičnih funkcija koje su od velike koristi prilikom donošenja redoslijeda sortiranja za zbirke.

Java 8 lambda može se učinkovito iskoristiti s Usporednik sučelje također. Detaljno objašnjenje lambda i Usporednik možete pronaći ovdje i kroniku o sortiranju i primjenama Usporednik možete pronaći ovdje.

U ovom vodiču, istražit ćemo nekoliko funkcija uvedenih za Usporednik sučelje u Javi 8.

2. Početak rada

2.1. Uzorak klase graha

Za primjere u ovom članku stvorimo Zaposlenik grah i koristite njegova polja za usporedbu i razvrstavanje:

javni razred Zaposlenik {Ime niza; int doba; dvostruka plaća; dugi mobilni; // konstruktori, getteri i postavljači}

2.2. Naši podaci o ispitivanju

Stvorimo i niz zaposlenika koji će se koristiti za pohranu rezultata našeg tipa u raznim testnim slučajevima u cijelom članku:

zaposlenici = novi zaposlenik [] {...};

Početno redoslijed elemenata zaposlenici bit će:

[Zaposlenik (ime = John, dob = 25, plaća = 3000,0, mobitel = 9922001), Zaposlenik (ime = Ace, dob = 22, plaća = 2000,0, mobitel = 5924001), Zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401)]

Kroz članak ćemo sortirati gore Zaposlenik niz pomoću različitih funkcija.

Za testne tvrdnje upotrijebit ćemo skup prethodno sortiranih nizova koje ćemo usporediti s rezultatima sortiranja (tj. zaposlenici niz) za različite scenarije.

Proglasimo nekoliko od ovih polja:

@Before public void initData () {sortedE EmployeesByName = novi zaposlenik [] {...}; sortedEfficieesByNameDesc = novi zaposlenik [] {...}; sortedEfficieesByAge = novi zaposlenik [] {...}; // ...}

Kao i uvijek, slobodno potražite naš GitHub link za cjeloviti kod.

3. Korištenje Usporednik.usporedba

Ovaj odjeljak obuhvaća inačice Usporednik.usporedba statička funkcija.

3.1. Varijanta odabira ključa

The Usporednik.usporedba statička funkcija prihvaća ključ za sortiranje Funkcija i vraća a Usporednik za tip koji sadrži ključ za sortiranje:

statički  Usporedba usporedbe (Function keyExtractor)

Da bismo to vidjeli na djelu, upotrijebimo Ime polje u Zaposlenik kao ključ za sortiranje i predaju njegovu referencu na metodu kao argument tipa Funkcija. The Usporednik vraćeno iz istog koristi se za sortiranje:

@Test public void whenComparing_thenSortedByName () {Comparator workerNameComparator = Comparator.comparing (Employee :: getName); Arrays.sort (zaposlenici, workerNameComparator); assertTrue (Arrays.equals (zaposlenici, sortedEfficieesByName)); }

Kao što vidite, zaposlenici vrijednosti polja sortirane su po imenu kao rezultat sortiranja:

[Zaposlenik (ime = Ace, dob = 22, plaća = 2000,0, mobitel = 5924001), Zaposlenik (ime = John, dob = 25, plaća = 3000,0, mobitel = 9922001), Zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401)] 

3.2. Birač ključeva i Usporednik Varijanta

Postoji još jedna opcija koja olakšava nadjačavanje prirodnog uređenja ključa za sortiranje davanjem Usporednik koji stvara prilagođeni poredak za ključ za sortiranje:

uspoređivanje statičkog usporednika (Funkcijski ključEkstraktor, Komparator ključKomparator)

Izmijenimo gornji test, nadjačavši prirodni redoslijed sortiranja po Ime polje pružanjem a Usporednik za sortiranje imena u opadajućem redoslijedu kao drugi argument za Usporednik.usporedba:

@Test public void whenComparingWithComparator_thenSortedByNameDesc () {Comparator workerNameComparator = Comparator.comparing (Employee :: getName, (s1, s2) -> {return s2.compareTo (s1);}); Arrays.sort (zaposlenici, workerNameComparator); assertTrue (Arrays.equals (zaposlenici, sortedE EmployeesByNameDesc)); }

Kao što vidite, rezultati su poredani u padajućem redoslijedu Ime:

[Zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401), Zaposlenik (ime = John, dob = 25, plaća = 3000,0, mobitel = 9922001), Zaposlenik (ime = Ace, dob = 22, plaća) = 2000,0, mobitel = 5924001)]

3.3. Koristeći Usporednik. obrnuto

Kada se pozove na postojeći Usporednik, metoda instance Usporednik. obrnuto vraća novi Usporednik to obrće redoslijed sortiranja izvornika.

Iskoristimo Usporednik koja sortira zaposlenike po Ime i obrnuti to tako da se zaposlenici sortiraju u opadajućem redoslijedu Ime:

@Test public void whenReversed_thenSortedByNameDesc () {Comparator workerNameComparator = Comparator.comparing (Employee :: getName); Usporednik workerNameComparatorReversed = workerNameComparator.reversed (); Arrays.sort (zaposlenici, workerNameComparatorReversed); assertTrue (Arrays.equals (zaposlenici, sortedE EmployeesByNameDesc)); }

Rezultati su poredani u padajućem redoslijedu Ime:

[Zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401), Zaposlenik (ime = John, dob = 25, plaća = 3000,0, mobitel = 9922001), Zaposlenik (ime = Ace, dob = 22, plaća) = 2000,0, mobitel = 5924001)]

3.4. Koristeći Usporednik.comparingInt

Postoji i funkcija Usporednik.comparingInt koja radi isto što i Usporednik.usporedba, ali potrebno je samo int selektori. Pokušajmo ovo s primjerom gdje naručujemo zaposlenici po dob:

@Test public void whenComparingInt_thenSortedByAge () {Comparator workerAgeComparator = Comparator.comparingInt (Employee :: getAge); Arrays.sort (zaposlenici, workerAgeComparator); assertTrue (Arrays.equals (zaposlenici, sortedEfficieesByAge)); }

Da vidimo kako zaposlenici Vrijednosti niza poredane su nakon sortiranja:

[Zaposlenik (ime = Ace, dob = 22, plaća = 2000,0, mobitel = 5924001), Zaposlenik (ime = John, dob = 25, plaća = 3000,0, mobitel = 9922001), Zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401)]

3.5. Koristeći Usporednik.comupoređivanjeLong

Slično onome za što smo radili int tipke, pogledajmo primjer korištenja Usporednik.comupoređivanjeLong razmotriti tip sortiranja tipa dugo naručivanjem zaposlenici niz po mobilni polje:

@Test public void whenComparingLong_thenSortedByMobile () {Comparator workerMobileComparator = Comparator.comparingLong (Employee :: getMobile); Arrays.sort (zaposlenici, workerMobileComparator); assertTrue (Arrays.equals (zaposlenici, sortedE EmployeesByMobile)); }

Da vidimo kako zaposlenici vrijednosti polja poredane su nakon sortiranja s mobilni kao ključ:

[Zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401), Zaposlenik (ime = Ace, dob = 22, plaća = 2000,0, mobitel = 5924001), Zaposlenik (ime = John, dob = 25, plaća = 3000,0, mobitel = 9922001)]

3.6. Koristeći Usporednik.comparingDouble

Opet, slično onome za što smo radili int i dugo tipke, pogledajmo primjer korištenja Usporednik.comparingDouble razmotriti tip sortiranja tipa dvostruko naručivanjem zaposlenici niz po plaća polje:

@Test public void whenComparingDouble_thenSortedBySalary () {Usporeditelj workerSalaryComparator = Comparator.comparingDouble (Zaposlenik :: getSalary); Arrays.sort (zaposlenici, workerSalaryComparator); assertTrue (Arrays.equals (zaposlenici, sortedE EmployeesBySalary)); }

Da vidimo kako zaposlenici vrijednosti polja poredane su nakon sortiranja s plaća kao ključ za sortiranje:

[Zaposlenik (ime = Ace, dob = 22, plaća = 2000,0, mobitel = 5924001), Zaposlenik (ime = John, dob = 25, plaća = 3000,0, mobitel = 9922001), Zaposlenik (ime = Keith, dob = 35, plaća) = 4000,0, mobitel = 3924401)]

4. Uzimajući u obzir prirodni poredak u Usporednik

Prirodni poredak definiran je ponašanjem Usporedive implementacija sučelja. Više informacija o razlici između Usporednik i uporabe Usporedive sučelje možete pronaći u ovom članku.

Provedimo Usporedive u našem Zaposlenik klase kako bismo mogli isprobati naturalOrder i obrnuti redoslijed funkcije Usporednik sučelje:

javna klasa Zaposlenik implementira Usporedivo {// ... @Override public int compareTo (Employee argE Employee) {return name.compareTo (argEfficiee.getName ()); }}

4.1. Koristeći prirodni poredak

The naturalOrder funkcija vraća Usporednik za vrstu povrata spomenutu u potpisu:

statički  Usporednik naturalOrder ()

S obzirom na gornju logiku usporedbe zaposlenika na temelju Ime polje, iskoristimo ovu funkciju za dobivanje a Usporednik koja sortira zaposlenici niz u prirodnom redoslijedu:

@Test public void whenNaturalOrder_thenSortedByName () {Usporeditelj workerNameComparator = Usporednik. naturalOrder (); Arrays.sort (zaposlenici, workerNameComparator); assertTrue (Arrays.equals (zaposlenici, sortedE EmployeesByName)); }

Da vidimo kako zaposlenici Vrijednosti niza poredane su nakon sortiranja:

[Zaposlenik (ime = Ace, dob = 22, plaća = 2000,0, mobitel = 5924001), Zaposlenik (ime = John, dob = 25, plaća = 3000,0, mobitel = 9922001), Zaposlenik (ime = Keith, dob = 35, plaća) = 4000,0, mobitel = 3924401)]

4.2. Korištenje obrnutog prirodnog poretka

Slično naturalOrder, iskoristimo obrnuti redoslijed metoda za generiranje a Usporednik što će proizvesti obrnuti redoslijed zaposlenici onome u naturalOrder primjer:

@Test public void whenReverseOrder_thenSortedByNameDesc () {Usporeditelj workerNameComparator = Usporednik. obrnuti redoslijed(); Arrays.sort (zaposlenici, workerNameComparator); assertTrue (Arrays.equals (zaposlenici, sortedE EmployeesByNameDesc)); }

Da vidimo kako zaposlenici Vrijednosti niza poredane su nakon sortiranja:

[Zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401), Zaposlenik (ime = John, dob = 25, plaća = 3000,0, mobitel = 9922001), Zaposlenik (ime = Ace, dob = 22, plaća) = 2000,0, mobitel = 5924001)]

5. Uzimajući u obzir nule vrijednosti u usporedbi

Ovaj odjeljak obuhvaća funkcije nullsFirst i nullsPosljednje, koji razmatraju null vrijednosti u naručivanju i zadržavanju null vrijednosti na početku ili na kraju redoslijeda naručivanja.

5.1. S obzirom na nulu prvo

Ubacimo nasumce null vrijednosti u zaposlenici niz:

[Zaposlenik (ime = John, dob = 25, plaća = 3000,0, mobitel = 9922001), null, Zaposlenik (ime = Ace, dob = 22, plaća = 2000,0, mobitel = 5924001), nula, Zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401)]

The nullsFirst funkcija će vratiti a Usporednik koji čuva sve nula na početku redoslijeda naručivanja:

@Test public void whenNullsFirst_thenSortedByNameWithNullsFirst () {Usporeditelj workerNameComparator = Comparator.comparing (Employee :: getName); Komparator workerNameComparator_nullFirst = Comparator.nullsFirst (workerNameComparator); Arrays.sort (zaposleniciArrayWithNulls, workerNameComparator_nullFirst); assertTrue (Arrays.equals (zaposleniciArrayWithNulls, sortedEfficieesArray_WithNullsFirst)); }

Da vidimo kako zaposlenici Vrijednosti niza poredane su nakon sortiranja:

[null, null, Zaposlenik (ime = Ace, dob = 22, plaća = 2000,0, mobitel = 5924001), Zaposlenik (ime = John, dob = 25, plaća = 3000,0, mobitel = 9922001), Zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401)]

5.2. S obzirom na Null Last

The nullsPosljednje funkcija će vratiti a Usporednik koji čuva sve nula na kraju slijeda narudžbe:

@Test public void whenNullsLast_thenSortedByNameWithNullsLast () {Comparator workerNameComparator = Comparator.comparing (Employee :: getName); Usporednik workerNameComparator_nullLast = Comparator.nullsLast (workerNameComparator); Arrays.sort (zaposleniciArrayWithNulls, workerNameComparator_nullLast); assertTrue (Arrays.equals (zaposleniciArrayWithNulls, sortedEfficieesArray_WithNullsLast)); }

Da vidimo kako zaposlenici Vrijednosti niza poredane su nakon sortiranja:

[Zaposlenik (ime = Ace, dob = 22, plaća = 2000,0, mobitel = 5924001), Zaposlenik (ime = John, dob = 25, plaća = 3000,0, mobitel = 9922001), Zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401), null, null]

6. Korištenje Usporednik.potom Usporedba

The zatimUporedi funkcija vam omogućuje postavljanje leksikografskog redoslijeda vrijednosti davanjem više ključeva za sortiranje u određenom slijedu.

Razmotrimo još jedan niz Zaposlenik razred:

someMoreEfficiees = novi zaposlenik [] {...};

Razmotrite sljedeći slijed elemenata u gornjem nizu:

[Zaposlenik (ime = Jake, dob = 25, plaća = 3000,0, mobitel = 9922001), Zaposlenik (ime = Jake, dob = 22, plaća = 2000,0, mobitel = 5924001), Zaposlenik (ime = Ace, dob = 22, plaća) = 3000,0, mobitel = 6423001), zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401)]

Napišimo slijed usporedbi kao dob nakon čega slijedi Ime i pogledajte poredak ovog polja:

@Test public void whenThenComparing_thenSortedByAgeName () {Comparator worker_Age_Name_Comparator = Comparator.comparing (Employee :: getAge) .thenComparing (Employee :: getName); Arrays.sort (someMoreEmploymentees, worker_Age_Name_Comparator); assertTrue (Arrays.equals (someMoreEfficiees, sortedEfficieesByAgeName)); }

Ovdje će narudžbu izvršiti do dob, a za vrijednosti s istim dob, narudžbu će izvršiti do Ime. Promotrimo to u slijedu koji dobijemo nakon sortiranja:

[Zaposlenik (ime = Ace, dob = 22, plaća = 3000,0, mobitel = 6423001), Zaposlenik (ime = Jake, dob = 22, plaća = 2000,0, mobitel = 5924001), Zaposlenik (ime = Jake, dob = 25, plaća = 3000,0, mobitel = 9922001), zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401)]

Koristimo drugu verziju zatimUporedi to je thenCombaringInt, promjenom leksikografskog slijeda u Ime nakon čega slijedi dob:

@Test public void whenThenComparing_thenSortedByNameAge () {Comparator zaposlenik_Name_Age_Comparator = Comparator.comparing (Employee :: getName) .thenComparingInt (Employee :: getAge); Arrays.sort (someMoreEfficiees, worker_Name_Age_Comparator); assertTrue (Arrays.equals (someMoreEfficiees, sortedEfficieesByNameAge)); }

Da vidimo kako zaposlenici Vrijednosti niza poredane su nakon sortiranja:

[Zaposlenik (ime = Ace, dob = 22, plaća = 3000,0, mobitel = 6423001), Zaposlenik (ime = Jake, dob = 22, plaća = 2000,0, mobitel = 5924001), Zaposlenik (ime = Jake, dob = 25, plaća = 3000,0, mobitel = 9922001), zaposlenik (ime = Keith, dob = 35, plaća = 4000,0, mobitel = 3924401)]

Slično tome, postoje funkcije zatimUpoređivanjeDugo i thenCombaringDouble za upotrebu dugo i dvostruko tipke za sortiranje.

7. Zaključak

Ovaj je članak vodič za nekoliko značajki uvedenih u Javi 8 za Usporednik sučelje.

Kao i obično, izvorni kod možete pronaći na Githubu.