Java

[Java] 김영한의 실전 자바 - 고급 3편 섹션7 스트림API

고쩡이 2025. 4. 12. 22:48

본문은 인프런 김영한T 자바 고급편3을 공부하고 직접 정리한 내용입니다:)

자바 스트림(Stream) API 핵심 정리


스트림(Stream)이란?

  • 데이터 흐름을 추상화한 자바 8 기능
  • Collection, 배열 등을 선언형 방식으로 연속 처리 가능
  • 마치 데이터가 "물 흐르듯" 연산 파이프라인을 따라 처리됨

🔄 스트림 처리 흐름

1. 스트림 생성

List<String> list = List.of("A", "B");
Stream<String> stream = list.stream();

 

2. 중간 연산 (Intermediate Operation)

데이터 변환 or 필터링

  • .filter() – 조건 필터링
  • .map() – 요소 변환

3. 최종 연산 (Terminal Operation)

스트림 소비 → 실행 시작!

  • .toList() – 리스트로 변환
  • .forEach() – 요소마다 실행

4. 내부 반복 방식 → 루프 직접 작성 필요 없음
→ forEach()가 내부에서 자동 반복

 

스트림 핵심 정리

선언형(Declarative) 무엇을 할지만 기술 (How → X)
지연 연산(Lazy) 중간 연산은 실행되지 않고 저장만 됨
최종 연산 필요 toList(), findFirst() 없으면 실행 X
일회성(Stream is Consumable) 한 번 쓰면 끝. 재사용 불가
파이프라인 처리 요소 하나가 연산을 "쭉" 통과하는 구조
단축 평가(Short-Circuiting) findFirst() 등에서 조건 만족하면 조기 종료 가능

예제 코드

List<String> result = names.stream()
    .filter(name -> name.startsWith("B"))
    .map(String::toUpperCase)
    .toList();
names.stream()
    .filter(name -> name.startsWith("B"))
    .map(String::toUpperCase)
    .forEach(System.out::println);

파이프라인 처리 vs 일괄 처리 비교 핵심

일괄 처리 한 연산을 전체 요소에 일괄 수행하고 다음 단계 진행
파이프라인 처리 한 요소가 한 번에 filter → map → collect 순서로 흐름

⚙️ 성능 최적화 - 지연 연산 활용 예

List<Integer> data = List.of(1, 2, 3, 4, 5, 6);

Integer result = data.stream()
    .filter(i -> i % 2 == 0)
    .map(i -> i * 10)
    .findFirst()  // 결과가 나오면 바로 연산 종료
    .get();       // Optional 에서 값 꺼내기

 

🧾 스트림 API의 장점 정리

  • 간결성: 코드 줄어듦
  • 가독성: 어떤 동작을 수행하는지 명확
  • 유연성: 다양한 연산 연결 가능
  • 최적화: 지연 연산 + 단축 평가로 연산 최소화
  • 함수형 스타일 지원: 선언형 코드로 전환 가능