본문 바로가기
Web Programming Language/JAVA

스트림(Stream) 활용 - 요소 정렬, 루핑(유소 개별 처리), 매칭(조건 만족 여부)

by manchesterandthecity 2025. 3. 6.

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() 그룹별 평균, 합, 개수 구하기

 

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

 

 

 

 

 

 

 

 

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

 

 

 

댓글