PHpullh
학습 라이브러리/Java/Stream API — 완전 정복

JAVA · 함수형/Stream

Stream API — 완전 정복

Java 8의 Stream API로 컬렉션을 함수형으로 처리합니다. 중간 연산과 최종 연산을 마스터합니다.

함수형/Stream중급StreamfiltermapcollectgroupingBy

핵심 설명

Java 8의 Stream API로 컬렉션을 함수형으로 처리합니다. 중간 연산과 최종 연산을 마스터합니다.

Java code

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

record Product(String name, int price, String category) {}

public class StreamDemo {
    public static void main(String[] args) {
        var products = List.of(
            new Product("Kotlin Book",  35000, "IT"),
            new Product("Java Book",    30000, "IT"),
            new Product("Python Guide", 28000, "IT"),
            new Product("Novel",        15000, "문학"),
            new Product("Manga",        12000, "문학")
        );

        // 중간 연산 체이닝
        List<String> result = products.stream()
            .filter(p -> p.price() >= 20000)
            .sorted(Comparator.comparing(Product::price).reversed())
            .map(p -> "%s: %,d원".formatted(p.name(), p.price()))
            .collect(Collectors.toList());
        result.forEach(System.out::println);

        // Collectors.groupingBy
        Map<String, List<Product>> byCategory =
            products.stream()
                .collect(Collectors.groupingBy(Product::category));

        // Collectors.groupingBy + downstream
        Map<String, IntSummaryStatistics> stats =
            products.stream()
                .collect(Collectors.groupingBy(
                    Product::category,
                    Collectors.summarizingInt(Product::price)));
        stats.forEach((cat, s) ->
            System.out.printf("%s: 평균 %,.0f원%n", cat, s.getAverage()));

        // partitioningBy — true/false 그룹
        Map<Boolean, List<Product>> partition =
            products.stream()
                .collect(Collectors.partitioningBy(p -> p.price() > 20000));

        // reduce
        int totalPrice = products.stream()
            .mapToInt(Product::price)
            .sum();
        OptionalInt maxPrice = products.stream()
            .mapToInt(Product::price)
            .max();

        // flatMap
        List<List<Integer>> nested = List.of(List.of(1,2), List.of(3,4));
        List<Integer> flat = nested.stream()
            .flatMap(Collection::stream)
            .collect(Collectors.toList());

        System.out.println("합계: " + totalPrice);
        System.out.println("최고가: " + maxPrice.orElse(0));
        System.out.println("평탄화: " + flat);
    }
}

학습 팁

Stream은 lazy evaluation을 사용합니다. 중간 연산은 최종 연산이 호출될 때까지 실행되지 않습니다. parallelStream()으로 병렬 처리가 가능하지만 항상 빠른 건 아닙니다.

주의할 점

Stream은 한 번 소비하면 재사용할 수 없습니다. IllegalStateException: stream has already been operated upon or closed가 나면 새 Stream을 생성하세요.

자주 묻는 질문

Stream API — 완전 정복란 무엇인가요?

Java 8의 Stream API로 컬렉션을 함수형으로 처리합니다. 중간 연산과 최종 연산을 마스터합니다.

Stream API — 완전 정복 학습 시 주의할 점은 무엇인가요?

Stream은 한 번 소비하면 재사용할 수 없습니다. IllegalStateException: stream has already been operated upon or closed 가 나면 새 Stream을 생성하세요.