Articles

egy Java-gyűjtemény szűrése egy lista alapján

áttekintés

egy gyűjtemény szűrése egy lista alapján egy általános üzleti logikai forgatókönyv. Rengeteg módja van ennek elérésére. Néhány azonban alulteljesítő megoldásokhoz vezethet, ha nem megfelelően hajtják végre.

ebben a bemutatóban összehasonlítunk néhány szűrési implementációt, majd megvitatjuk azok előnyeit és hátrányait.

A-minden hurok

kezdjük a legtöbb klasszikus szintaxis, a-minden hurok.

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

public class Employee { private Integer employeeNumber; private String name; private Integer departmentId; //Standard constructor, getters and setters.}

az egyszerűség kedvéért a következő módszereket is használjuk:

private List<Employee> buildEmployeeList() { return Arrays.asList( new Employee(1, "Mike", 1), new Employee(2, "John", 1), new Employee(3, "Mary", 1), new Employee(4, "Joe", 2), new Employee(5, "Nicole", 2), new Employee(6, "Alice", 2), new Employee(7, "Bob", 3), new Employee(8, "Scarlett", 3));}private List<String> employeeNameFilter() { return Arrays.asList("Alice", "Mike", "Bob");}

példánkhoz szűrjük az alkalmazottak első listáját a második lista alapján, a munkavállalói nevekkel, hogy csak az alkalmazottakkal rendelkező alkalmazottakat találjuk meg konkrét nevek.

most nézzük meg a hagyományos megközelítést – mindkét listán átfésüljük a mérkőzéseket:

@Testpublic void givenEmployeeList_andNameFilterList_thenObtainFilteredEmployeeList_usingForEachLoop() { List<Employee> filteredList = new ArrayList<>(); List<Employee> originalList = buildEmployeeList(); List<String> nameFilter = employeeNameFilter(); for (Employee employee : originalList) { for (String name : nameFilter) { if (employee.getName().equals(name)) { filteredList.add(employee); // break; } } } assertThat(filteredList.size(), is(nameFilter.size()));}

Ez egy egyszerű szintaxis, de elég bőbeszédű, és valójában elég hatékony. Egyszerűen fogalmazva, a két készlet derékszögű termékén keresztül iterálódik, hogy megkapjuk a választ.

még egy szünet hozzáadása a korai kilépéshez még mindig ugyanazon a sorrendben iterálódik, mint egy derékszögű termék az átlagos esetben.

Ha a munkavállalói lista méretét n-nek hívjuk, akkor a nameFilter ugyanolyan nagy lesz a sorrendben, ami O(n2) besorolást ad nekünk.

patakok és lista használata # tartalmaz

az előző módszert a lambdas használatával fogjuk újrafényképezni a szintaxis egyszerűsítése és az olvashatóság javítása érdekében. Használjuk a#listás módszert lambda szűrőként is:

@Testpublic void givenEmployeeList_andNameFilterList_thenObtainFilteredEmployeeList_usingLambda() { List<Employee> filteredList; List<Employee> originalList = buildEmployeeList(); List<String> nameFilter = employeeNameFilter(); filteredList = originalList.stream() .filter(employee -> nameFilter.contains(employee.getName())) .collect(Collectors.toList()); assertThat(filteredList.size(), is(nameFilter.size()));}

a Stream API használatával az olvashatóság jelentősen javult, de kódunk ugyanolyan hatékony marad, mint a korábbi módszerünk, mivel továbbra is a Descartes terméken keresztül iterálódik belsőleg. Így ugyanaz az O (n2) osztályozás van.

A

Hashsettel rendelkező patakok használata a teljesítmény javítása érdekében a HashSet # tartalmazza a módszert. Ez a módszer különbözik a # listától, mivel hash kódkeresést végez, így állandó számú műveletet ad nekünk:

@Testpublic void givenEmployeeList_andNameFilterList_thenObtainFilteredEmployeeList_usingLambdaAndHashSet() { List<Employee> filteredList; List<Employee> originalList = buildEmployeeList(); Set<String> nameFilterSet = employeeNameFilter().stream().collect(Collectors.toSet()); filteredList = originalList.stream() .filter(employee -> nameFilterSet.contains(employee.getName())) .collect(Collectors.toList()); assertThat(filteredList.size(), is(nameFilterSet.size()));}

a HashSet használatával a kód hatékonysága jelentősen javult, miközben nem befolyásolja az olvashatóságot. Mivel HashSet#tartalmaz fut állandó időben, már javult a besorolás O (n).

következtetés

ebben a gyors bemutatóban megtanultuk, hogyan kell szűrni egy gyűjteményt az értékek listájával, valamint a legegyszerűbb módszer használatának hátrányaival.

mindig figyelembe kell vennünk a hatékonyságot, mert a kódunk hatalmas adatkészletekben futhat, a teljesítményproblémák pedig katasztrofális következményekkel járhatnak ilyen környezetben.

Az ebben a cikkben bemutatott összes kód elérhető a GitHub-on.

Kezdje a tavaszi 5-ös és a tavaszi Boot 2-vel A Learn Spring tanfolyamon keresztül:

>>