개요
요즘 자바 Stream 문법을 공부하고 있다.
그런데 Stream을 사용해 List <Integer>나 List <String>, List <.. Dto>를 리턴할 때, 꼭 마지막에. collect(Collectors.toList()); 을 붙인다. 아래는 예시 코드이다.
List<...> streamList = list.stream()
...
.collect(Collectors.toList());
여기서 궁금한 점은 저 Collectors는 무엇인가이다.
그래서 오늘 Collectors 에 대해 정리해 봤다.
Collectors
위의 이미지는 Collectors 클래스에 달린 주석이다.
저 문장을 해석하면 다음과 같다.
Collectors의 구현체들은 Collection에 요소를 축적하거나, 다양한 기준에 따라 요소를 요약하는 등 유용한 축소 작업을 구현합니다.
다음은 미리 정의된 Collectors들을 사용하여 일반적인 가변 축소 작업을 수행하는 예시들입니다.
보다시피 Collectors의 역할은 크게 세 가지로 나뉜다.
- 자바의 Collection인 List, Map, Set 등에 데이터를 축적
- 하나의 변수로 만들기 위해 Stream을 계산 (최대, 최소, 합, 곱, 평균 등)
- Stream 요소들을 하나의 데이터로 변환 (여러 개로 나뉘어 있는 Stream을 하나의 Stream으로 결합)
toList(), toSet()
메서드의 이름대로 Stream 요소들을 List, Set에 수집할 때 사용되는 메서드이다.
List<String> list = stream.collect(Collectors.toList());
Set<String> set = stream.collect(Collectors.toSet());
toMap()
Stream의 요소들을 Map으로 수집한다. 이때, KeyMapper와 ValueMapper가 필요하다.
KeyMapper는 Stream 요소에서 Map의 Key를 추출하는 데 사용되고, ValueMapper는 Key의 값을 추출하는 데 사용된다.
아래의 코드는 문자열의 길이를 Key로, 문자열 자체를 Value로 하는 Map을 생성한다.
Map<Integer, String> map = stream.collect(Collectors.toMap(String::length, Function.identity()));
joining()
joining에 입력된 파라미터를 기준으로 요소들을 하나로 합칩니다.
아래 코드는 “, ”을 구분자, “[”을 접두사, “]”을 접미사로 하는 문자열을 반환하는 코드이다.
String result = stream.collect(Collectors.joining(", ", "[", "]"));
groupingBy()
Stream의 요소들을 주어진 기준에 따라 그룹화하여 Map으로 수집한다.
아래 코드는 문자열의 길이를 기준으로 문자열들을 그룹화하여 Map으로 반환한다.
Map<Integer, List<String>> groupedByLength = stream.collect(Collectors.groupingBy(String::length));
partitioningBy()
Stream의 요소들을 두 그룹으로 나누어 Map <Boolean, List <T>>로 수집한다. 기준이 되는 함수는 boolean 값을 반환하는 함수여야 한다.
아래 코드는 문자열의 길이가 3보다 긴지 아닌지에 따라 두 그룹으로 나누어 수집한다.
Map<Boolean, List<String>> partitioned = stream.collect(Collectors.partitioningBy(s -> s.length() > 3));
counting()
Stream의 요소의 개수를 센다.
int count = stream.collect(Collectors.counting());
reducing()
Stream의 요소들을 하나의 결과로 축소한다. 주로 집합적인 연산(예: 합계, 곱셈 등)을 수행할 때 사용된다.
아래 코드는 리스트에 있는 홀수의 곱을 계산한다.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int result = numbers.stream()
.filter(number -> number % 2 != 0) // 홀수 필터링
.reduce(1, (n1, n2) -> n1 * n2);
. reduce(1, (n1, n2) -> n1 * n2)
- 초기값 1로 시작하며, 스트림에서 필터링된 요소를 차례대로 n1과 n2에 곱한다.
- 연산 과정:
- 초기값: 1
- 첫 번째 요소 1: 1 * 1 = 1
- 두 번째 요소 3: 1 * 3 = 3
- 세 번째 요소 5: 3 * 5 = 15
summingDouble(), summingLong(), summingInt()
이 메서드들은 Stream 요소에서 특정 속성 값을 합산(summing)하여 결과를 반환한다.
- summingInt: Integer 타입 속성의 합산
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.collect(Collectors.summingInt(Integer::intValue));
System.out.println(sum); // 출력: 15
- summingLong: Long 타입 속성의 합산
List<Long> numbers = Arrays.asList(10L, 20L, 30L);
long sum = numbers.stream()
.collect(Collectors.summingLong(Long::longValue));
System.out.println(sum); // 출력: 60
- summingDouble: Double 타입 속성의 합산
List<Double> numbers = Arrays.asList(10.5, 20.0, 30.3);
double sum = numbers.stream()
.collect(Collectors.summingDouble(Double::doubleValue));
System.out.println(sum); // 출력: 60.8
averagingDouble(), averagingLong(), averagingInt()
이 메서드들은 Stream 요소의 평균을 계산한다.
- averagingInt: Integer 타입의 평균 계산
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
double average = numbers.stream()
.collect(Collectors.averagingInt(Integer::intValue));
System.out.println(average); // 출력: 3.0
- averagingLong: Long 타입의 평균 계산
List<Long> numbers = Arrays.asList(10L, 20L, 30L);
double average = numbers.stream()
.collect(Collectors.averagingLong(Long::longValue));
System.out.println(average); // 출력: 20.0
- averagingDouble: Double 타입의 평균 계산
List<Double> numbers = Arrays.asList(10.5, 20.0, 30.5);
double average = numbers.stream()
.collect(Collectors.averagingDouble(Double::doubleValue));
System.out.println(average); // 출력: 20.333..
'개발 일기' 카테고리의 다른 글
[개발 일기] 2025.01.20 - 함수형 인터페이스 (0) | 2025.01.20 |
---|---|
[개발 일기] 2025.01.19 - JWT(JWS, JWE) (0) | 2025.01.19 |
[개발 일기] 2025.01.17 - SSL (1) | 2025.01.17 |
[개발 일기] 2025.01.16 - B+Tree (0) | 2025.01.16 |
[개발 일기] 2025.01.15 - B-Tree (0) | 2025.01.15 |