1. 요소 기본 집계 (Aggregation)

집계(Aggregation)는 스트림의 요소들을 하나의 값으로 축소하는 기능을 의미하며, 이는 최종 처리 기능에 속한다.

즉, 집계 메소드들은 스트림 연산의 끝에서 실행된다.


스트림 API에서 제공하는 기본 집계 함수들은 다음과 같다:

🔹 기본 집계 메소드:

메소드 설명
count() 요소 개수를 반환 (long)
findFirst() 첫 번째 요소 반환 (Optional)
max(Comparator<T>) 최대값 반환 (Optional)
min(Comparator<T>) 최소값 반환 (Optional)
average() 평균값 반환 (OptionalDouble)
sum() 합 반환 (int, long, double)

 

📌 반환값의 특징

  • count(), sum() 등의 일부 메소드는 기본 데이터 타입(int, long, double)을 반환한다.
  • max(), min(), average() 등의 메소드는 Optional<T> 형태로 값을 반환한다. 이는 집계 대상 요소가 없을 경우 예외를 방지하기 위해 사용된다.

📝 예제 코드

int[] numbers = {2, 4, 6};
IntStream intStream = Arrays.stream(numbers);

// 요소 개수
long count = intStream.count();

// 요소 합
int sum = Arrays.stream(numbers)
                .sum();

// 요소 평균
OptionalDouble average = Arrays.stream(numbers)
                               .average();
double avgValue = average.orElse(0.0); // 값이 없을 경우 기본값 0.0 반환

// 최대값
OptionalInt max = Arrays.stream(numbers)
                        .max();
int maxValue = max.orElseThrow(); // 값이 없으면 예외 발생

 


17.11 요소 커스텀 집계 (Custom Aggregation)

자바의 기본 집계 메소드(sum(), average()) 외에도 사용자가 직접 집계 기능을 구현할 수 있도록 제공되는 메소드가 reduce()이다.

🔹 reduce() 메소드

스트림의 요소들을 하나의 값으로 축소(리덕션)하기 위해 사용된다.

 
  • accumulator: 두 개의 요소를 받아 하나로 줄이는 함수 (람다식으로 구현)
  • identity: 초기값 (집계 대상이 없을 때 기본값으로 사용)
Optional<T> reduce(BinaryOperator<T> accumulator)
T reduce(T identity, BinaryOperator<T> accumulator)

 

📌 reduce()를 사용한 합계 계산 예제

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// 요소들의 합 구하기
int sum = numbers.stream()
                 .reduce(0, (a, b) -> a + b);
System.out.println("합계: " + sum); // 출력: 15

// 요소들의 곱 구하기
int product = numbers.stream()
                     .reduce(1, (a, b) -> a * b);
System.out.println("곱셈 결과: " + product); // 출력: 120

// 최소값 구하기
Optional<Integer> min = numbers.stream()
                               .reduce(Integer::min);
System.out.println("최소값: " + min.orElse(-1)); // 출력: 1

 

💡 reduce()의 동작 방식

  1. 초기값(Identity)을 먼저 설정 (없으면 Optional로 반환)
  2. 첫 번째와 두 번째 요소를 연산하여 결과를 저장
  3. 결과와 세 번째 요소를 연산하여 새로운 결과를 저장
  4. 반복적으로 진행하여 최종 결과 도출

2. 요소 수집 (Collecting)

스트림의 요소들을 다른 컬렉션(List, Set, Map 등)으로 변환하거나, 집계 연산을 수행할 때 사용된다.

🔹 collect() 메소드

<R> R collect(Collector<? super T, A, R> collector)
  • Collector를 사용하여 스트림의 요소를 리스트, 집합, 맵 등으로 변환 가능
  • Collectors 유틸리티 클래스에서 다양한 Collector를 제공

1️⃣ 리스트 또는 셋으로 변환

List<String> names = students.stream()
                             .map(Student::getName)
                             .collect(Collectors.toList());

Set<Integer> scores = students.stream()
                              .map(Student::getScore)
                              .collect(Collectors.toSet());

2️⃣ Map으로 변환

Map<String, Integer> studentMap = students.stream()
                                          .collect(Collectors.toMap(
                                              Student::getName,   // Key: 학생 이름
                                              Student::getScore    // Value: 학생 점수
                                          ));

주의: toMap()을 사용할 때 중복된 키가 발생하면 IllegalStateException이 발생할 수 있다.
해결 방법: toMap()의 세 번째 인자로 (oldValue, newValue) -> newValue 제공.

 


3️⃣ 그룹핑 (GroupBy)

요소들을 특정 그룹으로 묶을 때 Collectors.groupingBy()를 사용한다.

Map<String, List<Student>> studentsByGender = students.stream()
                                                      .collect(Collectors.groupingBy(Student::getGender));

 

결과

{
    "남자": [Student1, Student2],
    "여자": [Student3, Student4]
}

4️⃣ 그룹별 집계

Map<String, Double> avgScoreByGender = students.stream()
                                               .collect(Collectors.groupingBy(
                                                   Student::getGender,
                                                   Collectors.averagingDouble(Student::getScore)
                                               ));

 

{
    "남자": 90.5,
    "여자": 88.0
}

정리

기능 메소드 설명
기본 집계 count(), sum(), average(), max(), min() 요소 개수, 합, 평균, 최댓값, 최솟값
커스텀 집계 reduce() 사용자 정의 방식으로 요소 축소
요소 수집 collect() 리스트, 셋, 맵 등으로 변환
그룹핑 groupingBy() 특정 기준으로 그룹핑
그룹별 집계 groupingBy() + averagingDouble() 그룹별 평균, 합, 개수 구하기

 

💡 스트림을 활용하면 데이터를 더욱 직관적으로 필터링, 변환, 집계할 수 있다!

 

 

 

 

 

 

 

 

참조:
이것이 자바다 _ 신용권

 

 

 

+ Recent posts