PHpullh
학습 라이브러리/Java/Collectors 고급 & Gatherers (Java 22+)

JAVA · 함수형/Stream

Collectors 고급 & Gatherers (Java 22+)

Collectors의 고급 기능과 Java 22의 Gatherers API.

함수형/Stream중급CollectorstoMapteeingjoininggroupingBy

핵심 설명

Collectors의 고급 기능과 Java 22의 Gatherers API.

Java code

import java.util.*;
import java.util.stream.*;

public class CollectorsAdvanced {
    record Employee(String name, String dept, int salary) {}

    public static void main(String[] args) {
        var employees = List.of(
            new Employee("Alice", "Engineering", 8000000),
            new Employee("Bob",   "Engineering", 7000000),
            new Employee("Carol", "Marketing",   6000000),
            new Employee("Dave",  "Marketing",   5500000),
            new Employee("Eve",   "Engineering", 9000000)
        );

        // toMap
        Map<String, Integer> nameSalary = employees.stream()
            .collect(Collectors.toMap(
                Employee::name,
                Employee::salary,
                Integer::sum  // 중복 키 처리
            ));

        // counting, averagingInt, summingInt
        Map<String, Long> countByDept = employees.stream()
            .collect(Collectors.groupingBy(
                Employee::dept,
                Collectors.counting()));

        Map<String, Double> avgSalaryByDept = employees.stream()
            .collect(Collectors.groupingBy(
                Employee::dept,
                Collectors.averagingInt(Employee::salary)));

        // joining
        String names = employees.stream()
            .map(Employee::name)
            .collect(Collectors.joining(", ", "[", "]"));
        System.out.println(names); // [Alice, Bob, Carol, Dave, Eve]

        // teeing (Java 12+) — 두 Collector를 동시에
        var result = employees.stream()
            .collect(Collectors.teeing(
                Collectors.minBy(Comparator.comparing(Employee::salary)),
                Collectors.maxBy(Comparator.comparing(Employee::salary)),
                (min, max) -> "최저: %s, 최고: %s".formatted(
                    min.map(Employee::name).orElse(""),
                    max.map(Employee::name).orElse(""))
            ));
        System.out.println(result);

        // collectingAndThen — 마지막에 변환
        List<String> topEarners = employees.stream()
            .filter(e -> e.salary() > 7000000)
            .collect(Collectors.collectingAndThen(
                Collectors.toList(),
                Collections::unmodifiableList));

        avgSalaryByDept.forEach((dept, avg) ->
            System.out.printf("%s: %,.0f원%n", dept, avg));
    }
}

학습 팁

Collectors.teeing()(Java 12+)은 동일한 스트림에서 두 가지 집계를 동시에 수행합니다. min과 max를 한 번의 순회로 구할 때 유용합니다.

주의할 점

Collectors.toMap()에서 중복 키가 있으면 IllegalStateException이 발생합니다. 세 번째 인자로 merge function을 반드시 제공하세요.

자주 묻는 질문

Collectors 고급 & Gatherers (Java 22+)란 무엇인가요?

Collectors의 고급 기능과 Java 22의 Gatherers API.

Collectors 고급 & Gatherers (Java 22+) 학습 시 주의할 점은 무엇인가요?

Collectors.toMap() 에서 중복 키가 있으면 IllegalStateException 이 발생합니다. 세 번째 인자로 merge function을 반드시 제공하세요.