Filtriranje Java zbirke po popisu

1. Pregled

Filtriranje a Kolekcija od strane a Popis je uobičajeni scenarij poslovne logike. Puno je načina da se to postigne. Međutim, neka mogu dovesti do rješenja s lošim učinkom ako se ne učine pravilno.

U ovom vodiču, usporedit ćemo neke implementacije filtriranja i razgovarati o njihovim prednostima i nedostacima.

2. Korištenje a Za svakoga Petlja

Započet ćemo s najklasičnijom sintaksom, petljom za svaku.

Za ovaj i sve ostale primjere u ovom članku koristit ćemo sljedeću klasu:

javni razred zaposlenik {private Integer workerNumber; privatni naziv niza; privatni Integer odjelId; // Standardni konstruktor, geteri i postavljači. }

Za sve primjere koristit ćemo i sljedeće metode radi jednostavnosti:

privatni popis buildEfficieeList () {return Arrays.asList (novi zaposlenik (1, "Mike", 1), novi zaposlenik (2, "John", 1), novi zaposlenik (3, "Mary", 1), novi zaposlenik ( 4, "Joe", 2), novi zaposlenik (5, "Nicole", 2), novi zaposlenik (6, "Alice", 2), novi zaposlenik (7, "Bob", 3), novi zaposlenik (8, "Scarlett", 3)); } privatni popis workerNameFilter () {return Arrays.asList ("Alice", "Mike", "Bob"); }

Za naš primjer filtrirat ćemo prvi popis Zaposlenici na temelju drugog popisa sa Zaposlenik imena za pronalaženje samo Zaposlenici s tim određenim imenima.

Pogledajmo sada tradicionalni pristup - pregledavajući oba popisa tražeći podudaranja:

@Test javna praznina givenEfficieeList_andNameFilterList_thenObtainFilteredEfficieeList_usingForEachLoop () {Popis filteredList = new ArrayList (); Popis originalList = buildEfficieeList (); Ime popisaFilter = workerNameFilter (); za (Zaposleni zaposlenik: originalList) {za (Naziv niza: nameFilter) {if (zaposlenik.getName (). je jednako (ime)) {filteredList.add (zaposlenik); // pauza; }}} assertThat (filteredList.size (), je (nameFilter.size ())); }

Ovo je jednostavna sintaksa, ali prilično je opširna i zapravo prilično neučinkovita. Jednostavno rečeno, to ponavlja kroz kartezijanski proizvod dvaju skupova kako bismo dobili naš odgovor.

Čak i dodavanje a pauza za rani izlazak i dalje će se ponavljati istim redoslijedom kao i kartezijski proizvod u prosječnom slučaju.

Ako zovemo veličinu popisa zaposlenika n, zatim nameFilter bit će na narudžbi jednako veliko, dajući nam an O (n2) klasifikacija.

3. Korištenje Streamova i Lista # sadrži

Sada ćemo refaktorizirati prethodnu metodu pomoću lambda-a radi pojednostavljenja sintakse i poboljšanja čitljivosti. Koristimo i Lista # sadrži metoda kao lambda filter:

@Test javna praznina givenEfficieeList_andNameFilterList_thenObtainFilteredEfficieeList_usingLambda () {Popis filteredList; Popis originalList = buildEfficieeList (); Ime popisaFilter = workerNameFilter (); filteredList = originalList.stream () .filter (zaposlenik -> nameFilter.contens (worker.getName ())) .collect (Collectors.toList ()); assertThat (filteredList.size (), je (nameFilter.size ())); }

Korištenjem Stream API, čitljivost je znatno poboljšana, ali naš kôd ostaje jednako neučinkovit kao i naša prethodna metoda, jer je još uvijek interno prolazeći kroz kartezijanski proizvod. Dakle, imamo isto O (n2) klasifikacija.

4. Korištenje streama s HashSet

Da bismo poboljšali performanse, moramo koristiti HashSet # sadrži metoda. Ova se metoda razlikuje od Lista # sadrži jer izvodi a hash kod pretraživanja, dajući nam konstantni broj operacija:

@Test javna praznina givenEfficieeList_andNameFilterList_thenObtainFilteredEfficieeList_usingLambdaAndHashSet () {Popis filteredList; Popis originalList = buildEfficieeList (); Postavite nameFilterSet = workerNameFilter (). Stream (). Collect (Collectors.toSet ()); filteredList = originalList.stream () .filter (zaposlenik -> nameFilterSet.contens (worker.getName ())) .collect (Collectors.toList ()); assertThat (filteredList.size (), je (nameFilterSet.size ())); }

Pomoću HashSet, naša se učinkovitost koda znatno poboljšala, a da pritom nije utjecala na čitljivost. Od HashSet # sadrži radi u stalnom vremenu, poboljšali smo klasifikaciju na Na).

5. Zaključak

U ovom smo brzom vodiču naučili kako filtrirati a Kolekcija od strane a Popis vrijednosti i nedostaci korištenja onoga što se može činiti najjednostavnijom metodom.

Uvijek moramo razmotriti učinkovitost, jer bi naš kôd mogao završiti s ogromnim skupovima podataka, a problemi s izvedbom u takvim bi okruženjima mogli imati katastrofalne posljedice.

Sav kôd predstavljen u ovom članku dostupan je na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found