Java-gyűjtemény szűrése listán

1. Áttekintés

Szűrés a Gyűjtemény által a Lista egy általános üzleti logikai forgatókönyv. Ennek elérésére rengeteg módszer létezik. Egyesek azonban nem megfelelő megoldásokhoz vezethetnek alulteljesítő megoldásokhoz.

Ebben az oktatóanyagban összehasonlítunk néhány szűrési megvalósítást, és megvitatjuk azok előnyeit és hátrányait.

2. Használja a Az egyes Hurok

Kezdjük a legklasszikusabb szintaxissal, egy-egy hurokkal.

Ehhez és a cikk összes többi példájához a következő osztályt fogjuk használni:

public class Alkalmazott {private Integer alkalmazottszám; privát karakterlánc neve; magán Integer osztályId; // Normál kivitelező, mérőeszközök és beállítók. }

Az egyszerűség kedvéért minden példához a következő módszereket is felhasználjuk:

privát lista buildEmployeeList () {return Arrays.asList (új alkalmazott (1, "Mike", 1), új alkalmazott (2, "John", 1), új alkalmazott (3, "Mary", 1), új alkalmazott ( 4, "Joe", 2), új alkalmazott (5, "Nicole", 2), új alkalmazott (6, "Alice", 2), új alkalmazott (7, "Bob", 3), új alkalmazott (8, "Scarlett" (3)); } private List workerNameFilter () {return Arrays.asList ("Alice", "Mike", "Bob"); }

Példánkhoz szűrjük az első listát Alkalmazottak a második lista alapján Munkavállaló nevek csak a Alkalmazottak azokkal a konkrét nevekkel.

Nézzük meg a hagyományos megközelítést - mindkét listát végiglapozva keresi az egyezéseket:

@Test public void givenEmployeeList_andNameFilterList_thenObtainFilteredEmployeeList_usingForEachLoop () {List filteredList = new ArrayList (); List originalList = buildEmployeeList (); List nameFilter = alkalmazottNévFilter (); for (Munkavállalói alkalmazott: originalList) {for (Karakterlánc neve: névFilter) {if (alkalmazott.címNév (). egyenlő (név)) {szűrtLista.add (alkalmazott); // szünet; }}} assertThat (filteredList.size (), is (nameFilter.size ())); }

Ez egy egyszerű szintaxis, de meglehetősen részletes és valójában nem hatékony. Egyszerűen fogalmazva a két készlet derékszögű szorzatán keresztül ismétlődik hogy megkapjuk a válaszunkat.

Még a szünet a korai kilépés továbbra is ugyanazon a sorrenden fog ismétlődni, mint egy derékszögű termék átlagos esetben.

Ha hívjuk a munkavállalói lista méretét n, azután nameFilter ugyanolyan nagy sorrendben lesz, adva nekünk an O (n2) osztályozás.

3. A folyamok és A # lista tartalmazza

Most átdolgozzuk az előző módszert lambda használatával a szintaxis egyszerűsítése és az olvashatóság javítása érdekében. Használjuk a A # lista tartalmazza módszer, mint a lambda szűrő:

@Test public void givenEmployeeList_andNameFilterList_thenObtainFilteredEmployeeList_usingLambda () {List filteredList; List originalList = buildEmployeeList (); List nameFilter = alkalmazottNévFilter (); filteredList = originalList.stream () .filter (alkalmazott -> névFilter.contains (alkalmazott.getNév ())) .collect (Gyűjtők.lista ()); assertThat (filteredList.size (), is (nameFilter.size ())); }

A Stream API, az olvashatóság nagymértékben javult, de a kódunk ugyanolyan hatástalan, mint az előző módszerünk, mert az továbbra is iterálva a derékszögű terméken belül. Így nálunk is ugyanaz van O (n2) osztályozás.

4. A folyamok használata a HashSet

A teljesítmény javításához használnunk kell a A HashSet # tartalmazza módszer. Ez a módszer eltér a A # lista tartalmazza mert elvégzi a hash kód keresés, amely állandó idejű műveletek számát adja meg:

@Test public void givenEmployeeList_andNameFilterList_thenObtainFilteredEmployeeList_usingLambdaAndHashSet () {List filteredList; List originalList = buildEmployeeList (); Set nameFilterSet = alkalmazottNévFilter (). Stream (). Collect (Collectors.toSet ()); filteredList = originalList.stream () .filter (alkalmazott -> névFilterSet.contains (alkalmazott.getName ())) .collect (Collectors.toList ()); assertThat (filteredList.size (), is (nameFilterSet.size ())); }

Használva HashSet, kód hatékonyságunk nagymértékben javult, miközben nem befolyásolta az olvashatóságot. Mivel A HashSet # tartalmazza állandó időben fut, tovább javítottuk a besorolást Tovább).

5. Következtetés

Ebben a gyors bemutatóban megtanultuk a Gyűjtemény által a Lista az értékek és a legegyszerűbbnek tűnő módszer alkalmazásának hátrányai.

Mindig figyelembe kell vennünk a hatékonyságot, mert a kódunk hatalmas adatállományokban futhat, és a teljesítményproblémák katasztrofális következményekkel járhatnak ilyen környezetben.

A cikkben bemutatott összes kód elérhető a GitHubon.