Articles

필터링 Java 컬렉션에 의해 목록

개요

필터링하여 컬렉션의 목록은 일반적인 비즈니스 로직의 시나리오. 이를 달성하기위한 많은 방법이 있습니다. 그러나 일부는 제대로 수행되지 않으면 실적이 저조한 솔루션으로 이어질 수 있습니다.

이 튜토리얼에서는 몇 가지 필터링 구현을 비교하고 장점과 단점에 대해 설명합니다.

For-Each 루프를 사용하여

가장 고전적인 구문 인 for-each 루프로 시작하겠습니다.

이와 모든 다른 이 문서에서 예,우리가 사용하여 다음과 같은 종류:

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

우리는 또한 다음과 같은 방법을 사용한 모든 예 단순화 하기 위해

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");}

우리의 예를 들어, 우리는 필터가 첫 번째 목록의 기준으로 직원에게는 두 번째 목록과 함께 직원의 이름을 찾는 직원만으로 그 특정한 이름입니다.

이제 전통적인 접근 방식을 살펴 보겠습니다–일치를 찾는 두 목록을 반복합니다:이것은 간단한 구문이지만 상당히 장황하고 실제로는 매우 비효율적입니다. 간단히 말해서,그것은 우리의 대답을 얻기 위해 두 세트의 데카르트 곱을 반복합니다.

일찍 종료하기 위해 휴식을 추가하더라도 평균 사례에서 데카르트 곱과 동일한 순서로 반복됩니다.

우리가 직원 목록 n 의 크기를 호출하면 nameFilter 는 우리에게 O(n2)분류를 제공,그냥 큰 순서에있을 것입니다.

를 사용하여 스트림 및 목록#담

우리는 이제 리팩터링 방법을 사용하여 람다를 구문을 간소화하고 가독성을 높입니다. 자는 또한 목록을 사용하여#포함하는 방법으로 람다 filter:

@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()));}

를 사용하여 스트림 API,가독성이 크게 개선되었지만,우리의 코드를 유지하므로 비효율적으로 우리의 이전 방법이기 때문에 그것은 여전히 반복을 통해 데카르트 제품을 내부적으로 합니다. 따라서 우리는 동일한 O(n2)분류를가집니다.

HashSet 과 함께 스트림 사용

성능을 향상 시키려면 HashSet#contains 메소드를 사용해야합니다. 이 방법과 다릅 목록#담을 수행하므로 해시 코드를 조회,주는 우리에게 일정한 시간의 번호를 운영:

@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()));}

를 사용하여 HashSet,우리의 코드를 효율은 크게 향상에 영향을 미치는 것은 아니지만 가독성을 높입니다. HashSet#에는 일정한 시간에 실행이 포함되어 있으므로 분류를 O(n)로 개선했습니다.

결론

이 빠른 튜토리얼에서,우리는 어떻게 배웠을 필터링하여 컬렉션에 값의 목록과 단점이 있는 것처럼 보일 수 있는 가장 간단한 방법입니다.

우리는 항상 효율성을 고려하기 때문에 우리의 코드가 끝까지 실행하는 거대한 데이터 설정 및 성능 문제를 해결할 수 있는 치명적인 결과 같은 환경입니다.

이 기사에 제시된 모든 코드는 GitHub 에서 사용할 수 있습니다.

시작을 봄 5 봄 2 부팅을 통해 배울 봄 course:

>>교육 과정을 살펴보세요