Java 8 Collectors 예제
1. 개요
Stream 처리의 마지막 단계에서 사용되는 Java 8 Collectors 살펴 보겠습니다 .
2. Stream.collect () 메소드
Stream.collect () 는 Java 8의 Stream API 터미널 메소드 중 하나입니다 . 이를 통해 Stream 인스턴스에 보유 된 데이터 요소에 대해 변경 가능한 접기 작업 (요소를 일부 데이터 구조로 재 포장 및 추가 논리 적용, 연결 등)을 수행 할 수 있습니다.
이 작업에 대한 전략은 수집기 인터페이스 구현을 통해 제공됩니다 .
3. Collectors
미리 정의 된 모든 구현은 Collectors 클래스 에서 찾을 수 있습니다 . 가독성을 높이기 위해 다음 정적 가져 오기를 사용하는 것이 일반적입니다.
또는 선택한 단일 가져 오기 수집기 :
다음 예제에서는 다음 목록을 재사용합니다.
3.1. Collectors.toList ()
ToList 수집기는 모든 Stream 요소를 List 인스턴스 로 수집하는 데 사용할 수 있습니다 . 기억해야 할 중요한 것은 이 메소드를 사용하여 특정 List 구현을 가정 할 수 없다는 사실입니다 . 이것을 더 잘 제어하려면 대신 toCollection을 사용하십시오.
하자가 생성 스트림 요소의 순서를 나타내는 인스턴스를하고로를 수집 목록의 예 :
3.2. Collectors.toSet ()
ToSet 수집기는 모든 Stream 요소를 Set 인스턴스 로 수집하는 데 사용할 수 있습니다 . 기억해야 할 중요한 것은 이 메소드를 사용하여 특정 Set 구현을 가정 할 수 없다는 사실입니다 . 이것을 더 잘 제어하려면 toCollection을 대신 사용할 수 있습니다 .
의는 만들어 보자 스트림 요소의 순서를 나타내는 인스턴스를하고로 수집 설정 예 :
세트는 중복 요소를 포함하지 않습니다. 컬렉션에 서로 같은 요소가 포함 된 경우 결과 집합에 한 번만 나타납니다 .
3.3. Collectors.toCollection ()
이미 알고 있듯이 toSet 및 toList 콜렉터를 사용할 때는 해당 구현을 가정 할 수 없습니다. 사용자 정의 구현을 사용하려면 제공된 콜렉션을 선택 하여 toCollection 콜렉터 를 사용해야합니다 .
의는 만들어 보자 스트림 요소의 순서를 나타내는 인스턴스를하고로를 수집 LinkedList의의 예 :
변경 불가능한 콜렉션에서는 작동하지 않습니다. 이 경우 사용자 정의 수집기 구현을 작성하거나 collectAndThen을 사용해야 합니다 .
3.4. Collectors.toMap()
ToMap 수집기는 Stream 요소를 Map 인스턴스 로 수집하는 데 사용할 수 있습니다 . 이렇게하려면 두 가지 기능을 제공해야합니다.
keyMapper
valueMapper
keyMapper 는 Stream 요소 에서 Map 키 를 추출하는 데 사용 되며 valueMapper 는 지정된 키와 관련된 값을 추출하는 데 사용됩니다.
문자열을 키로 저장하고 길이를 값으로 저장 하는 Map에 해당 요소를 수집합시다 .
Function.identity () 는 동일한 값을 수락하고 반환하는 함수를 정의하기위한 바로 가기입니다.
컬렉션에 중복 요소가 포함되어 있으면 어떻게됩니까? toSet 과 달리 toMap 은 중복을 자동으로 필터링하지 않습니다. 이해할 수 있습니다.이 키에 어떤 값을 선택해야하는지 어떻게 알 수 있습니까?
참고 toMap이 값도 동일 여부도 평가하지 않습니다. 중복 키가 보이면 즉시 IllegalStateException을 발생 시킵니다.
키 충돌이있는 경우 다른 서명과 함께 toMap 을 사용해야합니다 .
여기서 세 번째 인수는 BinaryOperator 이며 충돌 처리 방법을 지정할 수 있습니다. 이 경우 동일한 문자열의 길이가 항상 동일하다는 것을 알기 때문에이 두 충돌 값 중 하나만 선택합니다.
3.5. Collectors.collectingAndThen()
CollectingAndThen 은 수집 이 끝난 직후 결과에 대해 다른 작업을 수행 할 수있는 특수 수집기입니다.
Stream 요소를 List 인스턴스 로 수집 한 다음 결과를 ImmutableList 인스턴스 로 변환합니다 .
3.6. Collectors.joining()
Stream 요소 를 결합하는 데 결합 수집기를 사용할 수 있습니다 .
다음을 수행하여 함께 참여할 수 있습니다.
결과는 다음과 같습니다.
사용자 정의 구분 기호, 접두사, 접미사를 지정할 수도 있습니다.
결과는 다음과 같습니다.
또는 당신은 쓸 수 있습니다 :
결과는 다음과 같습니다.
3.7. Collectors.counting()
카운팅 은 모든 스트림 요소를 간단히 카운팅 할 수있는 간단한 수집기입니다 .
이제 다음과 같이 쓸 수 있습니다 :
3.8. Collectors.summarizingDouble/Long/Int()
SummarizingDouble / Long / Int 는 추출 된 요소 스트림 에서 숫자 데이터에 대한 통계 정보를 포함하는 특수 클래스를 리턴하는 콜렉터입니다 .
다음을 수행하여 문자열 길이에 대한 정보를 얻을 수 있습니다.
이 경우 다음이 적용됩니다.
3.9. Collectors.averagingDouble/Long/Int()
AveragingDouble / Long / Int 는 추출 된 요소의 평균을 반환하는 수집기입니다.
다음을 수행하여 평균 문자열 길이를 얻을 수 있습니다.
3.10. Collectors.summingDouble/Long/Int()
SummingDouble / Long / Int 는 추출 된 요소의 합계를 반환하는 수집기입니다.
다음을 수행하여 모든 문자열 길이의 합계를 얻을 수 있습니다.
3.11. Collectors.maxBy()/minBy()
MaxBy / MinBy 수집기 는 제공된 Comparator 인스턴스 에 따라 스트림 의 가장 큰 / 가장 작은 요소를 반환합니다 .
다음을 수행하여 가장 큰 요소를 선택할 수 있습니다.
반환 된 값은 Optional 인스턴스에 래핑됩니다 . 이로 인해 사용자는 빈 수집 코너 케이스를 다시 생각해야합니다.
3.12. Collectors.groupingBy()
GroupingBy 콜렉터는 일부 특성별로 오브젝트를 그룹화하고 결과를 Map 인스턴스 에 저장하는 데 사용됩니다 .
문자열 길이별로 그룹화하고 그룹화 결과를 Set 인스턴스 에 저장할 수 있습니다 .
결과는 다음과 같습니다.
주의의 두 번째 인수 것을 groupingBy의 방법은이다 수집기 당신은 어떤 자유롭게 사용할 수 있습니다 수집기를 원하는.
3.13. Collectors.partitioningBy ()
PartitioningBy 는 Predicate 인스턴스 를 허용하고 스트림 요소를 부울 값을 키로, 컬렉션을 값으로 저장 하는 Map 인스턴스 로 수집 하는 groupingBy 의 특수한 경우입니다 . 은 "진정한"키 아래에, 당신은 주어진 일치하는 요소의 모음 찾을 수 있습니다 술어를 하고 "거짓"키에, 당신은 주어진 일치하지 않는 요소의 컬렉션을 찾을 수 있습니다 술어를 .
당신은 쓸 수 있습니다:
다음을 포함하는 맵이 생성됩니다.
3.14. Collectors.teeing ()
지금까지 배운 콜렉터를 사용하여 지정된 스트림 에서 최대 및 최소 수를 찾으십시오 .
여기서 우리는 두 개의 다른 수집기를 사용하고 그 두 개의 결과를 결합하여 의미있는 것을 만듭니다. Java 12 이전에는 이러한 사용 사례를 다루기 위해 주어진 스트림에서 두 번 작업하고 중간 결과를 임시 변수에 저장 한 다음 그 결과를 결합해야했습니다.
다행히도 Java 12는 내장 된 수집기를 제공하여이를 대신하여 이러한 단계를 처리합니다. 두 수집기와 결합기 기능을 제공하기 만하면됩니다.
이 새로운 컬렉터 때문에 티 두 개의 서로 다른 방향을 향해 지정된 스트림을, 그것은라고 티잉 :
이 예제는 core-java-12 프로젝트의 GitHub에서 사용할 수 있습니다 .
4. 커스텀 컬렉터
Collector 구현을 작성하려면 Collector 인터페이스를 구현하고 세 가지 일반 매개 변수를 지정해야합니다.
T
– 수집에 사용 가능한 객체의 유형
A
– 변경 가능한 누산기 객체의 유형
R
– 최종 결과의 유형.
ImmutableSet 인스턴스에 요소를 수집하기위한 Collector 예제를 작성해 봅시다 . 올바른 유형을 지정하여 시작합니다.
내부 컬렉션 작업 처리를 위해 변경 가능한 컬렉션이 필요하기 때문에 ImmutableSet 을 사용할 수 없습니다 . 우리는 일시적으로 객체를 축적 할 수있는 다른 변경 가능한 컬렉션이나 클래스를 사용해야합니다.이 경우에는 ImmutableSet.Builder 를 사용하여 5 가지 메소드를 구현해야합니다.
공급자 <ImmutableSet.Builder > 공급자 ()
BiConsumer <ImmutableSet.Builder , T> 누산기 ()
BinaryOperator <ImmutableSet.Builder > 결합기 ()
함수 <ImmutableSet.Builder , ImmutableSet > 마무리 장치 ()
*<특성> 특성 설정 ()*
supplier () 메소드는빈 누산기 인스턴스를 생성하는 Supplier 인스턴스를반환 하므로이 경우 간단히 작성할 수 있습니다.
accumulator () 메소드는 기존 accumulator 객체에새 요소를 추가하는 데 사용되는 함수를 리턴하므로 Builder 의 add 메소드를사용하십시오.
combiner () 메소드는 두 개의 누산기를 병합하는 데 사용되는 함수를 리턴합니다.
finisher () 메소드는 누산기를 최종 결과 유형으로 변환하는 데 사용되는 함수를 리턴 하므로이 경우 빌더 의 빌드 메소드만 사용합니다.
attributes () 메서드는 내부 최적화에 사용될 몇 가지 추가 정보를 Stream에 제공하는 데 사용됩니다. 요소가에서 주문이 경우, 우리는 관심을 지불하지 않는 설정 우리가 사용되도록 Characteristics.UNORDERED을 . 이 주제에 대한 자세한 정보를 얻으려면 특성 'JavaDoc을확인하십시오.
사용법과 함께 완전한 구현은 다음과 같습니다.
그리고 여기 실제로 행동하십시오 :
5. 결론
이 기사에서는 자세한 Java 8 수집기 를 살펴보고 구현 방법을 보여주었습니다. Java에서 병렬 처리 기능을 향상시키는 프로젝트 중 하나를 확인하십시오 .
참고
Last updated
Was this helpful?