Development/Java

Java 스트림(Stream) 완벽 가이드

최라온 2025. 5. 14. 15:27
728x90
반응형
SMALL

Java 스트림(Stream) 완벽 가이드

Java 8부터 도입된 Stream API는 컬렉션 데이터를 함수형 스타일로 처리할 수 있도록 도와주는 강력한 도구입니다. 반복문 없이 선언적으로 데이터를 필터링, 매핑, 정렬, 집계하는 등 다양한 연산을 간결하게 구현할 수 있습니다.

1. Stream이란?

Stream은 컬렉션(List, Set 등)의 요소들을 하나씩 처리하며, 파이프라인 방식으로 연산을 연결해 구성할 수 있는 데이터 처리 흐름입니다. 데이터 자체를 변경하지 않고, 일관성 있는 결과를 반환합니다.

2. Stream 특징

  • 선언형 코드: for문 없이 간결한 문법
  • 중간 연산과 최종 연산 구분: filter, map 등은 중간 연산 / collect, count 등은 최종 연산
  • 지연 연산(Lazy Evaluation): 최종 연산이 호출될 때까지 실행되지 않음
  • 병렬 처리 지원: parallelStream()으로 멀티코어 활용

3. 기본 사용법

List names = Arrays.asList("Kim", "Lee", "Park");

names.stream()
     .filter(name -> name.startsWith("K"))
     .forEach(System.out::println);

위 예제는 "K"로 시작하는 이름만 필터링하여 출력합니다.

4. 주요 연산 종류

4.1 filter()

조건에 맞는 요소만 추출

list.stream().filter(x -> x > 10);

4.2 map()

요소 변환

list.stream().map(String::toUpperCase);

4.3 sorted()

정렬

list.stream().sorted();

4.4 collect()

결과 수집

List result = list.stream()
                          .filter(x -> x.length() > 3)
                          .collect(Collectors.toList());

4.5 reduce()

요소 누적 연산

int sum = list.stream().reduce(0, Integer::sum);

5. 병렬 스트림 (parallelStream)

멀티코어 환경에서 성능 향상을 위해 병렬 처리 가능

list.parallelStream().forEach(System.out::println);

단, 데이터 양이 작거나 정렬 순서가 중요할 경우에는 stream() 사용 권장

6. 실무 예제 - 사용자 리스트 필터링

class User {
    String name;
    int age;
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

List users = Arrays.asList(
    new User("Kim", 30),
    new User("Lee", 25),
    new User("Park", 40)
);

List result = users.stream()
    .filter(u -> u.age >= 30)
    .map(u -> u.name)
    .collect(Collectors.toList());

7. 주의할 점

  • stream은 재사용 불가: 한 번 소비하면 다시 사용할 수 없음
  • 성능 고려: 너무 많은 중간 연산은 지연 발생
  • 상태 유지 연산 지양: 외부 상태 변경하지 않도록 작성

8. 결론

Stream API는 Java 컬렉션을 선언형 방식으로 간결하게 처리할 수 있도록 도와줍니다. filter, map, reduce 등 핵심 연산을 이해하고 적절히 조합하면 코드 품질과 생산성이 크게 향상됩니다.

728x90
반응형
LIST