본문 바로가기
language/java

Java Stream API 기초 완벽 이해하기

by 죄니안죄니 2026. 5. 27.
반응형

Java Stream API 기초 완벽 이해하기

Java 8 이후 Java 개발 스타일을 완전히 바꿔버린 핵심 기능이 바로:

Stream API

입니다.

현대 Java 실무에서는:

  • 데이터 가공
  • 리스트 변환
  • 필터링
  • 집계 처리
  • 병렬 처리

전부 Stream 기반으로 작성하는 경우가 많습니다.

예:

 
list.stream()
    .filter(x -> x > 10)
    .map(x -> x * 2)
    .forEach(System.out::println);
 

이런 코드가 바로 Stream 스타일입니다.

처음 보면:

“for문 없애는 문법?”
 

처럼 보일 수 있지만,

실제로 Stream은:

  • 내부 반복(Internal Iteration)
  • Lazy Evaluation
  • Pipeline
  • 함수형 프로그래밍
  • 병렬 처리

까지 연결되는 매우 중요한 Java 핵심 기능입니다.

이번 글에서는:

  • Stream이란?
  • 왜 등장했는가
  • 내부 반복 구조
  • map/filter/reduce
  • lazy evaluation
  • pipeline 구조
  • 실무 사용 전략

까지 깊게 정리해보겠습니다.


1. Stream이란?

Stream API 는:

데이터를 함수형 방식으로 처리하기 위한 API

입니다.


2. 핵심 목표

매우 중요.

“데이터 처리 로직을 선언적으로 작성”
 

하는 것.


3. 기존 Java 방식

예:

 
List<Integer> result =
    new ArrayList<>();

for (Integer n : numbers) {

    if (n > 10) {
        result.add(n * 2);
    }
}
 

4. 문제점

로직보다:

반복 제어 코드
 

가 더 많음.

즉:

  • iterator
  • loop
  • 임시 변수

등 보일러플레이트 증가.


5. Stream 방식

 
List<Integer> result =
    numbers.stream()
           .filter(n -> n > 10)
           .map(n -> n * 2)
           .toList();
 

6. 훨씬 선언적

핵심:

무엇을 할지 중심
 

으로 표현.


7. Stream은 Collection이 아니다

매우 중요.

많은 초보자가 헷갈림.


8. Collection vs Stream


항목 Collection Stream
목적 데이터 저장 데이터 처리
특징 mutable 가능 일회성 처리
반복 방식 외부 반복 내부 반복

9. Stream은 “흐름”

즉:

데이터 자체가 아니라
데이터 처리 파이프라인
 

입니다.


10. Stream 생성

대표 방법:

 
list.stream()
 

11. 배열도 가능

 
Arrays.stream(arr)
 

12. Stream.of()

 
Stream.of(1, 2, 3)
 

13. 핵심 구조

Stream은 보통:

생성
↓
중간 연산
↓
최종 연산
 

구조.


14. 예시 전체 흐름

 
list.stream()
    .filter(x -> x > 10)
    .map(x -> x * 2)
    .forEach(System.out::println);
 

15. 분석


단계 역할
stream() Stream 생성
filter() 중간 연산
map() 중간 연산
forEach() 최종 연산

16. 중간 연산(Intermediate Operation)

대표:

  • filter
  • map
  • sorted
  • distinct

17. 특징

매우 중요.

중간 연산은 즉시 실행 안 됨
 

18. 이것이 Lazy Evaluation

Lazy evaluation 이란:

실제 필요할 때까지 실행 미루는 것

입니다.


19. 예시

 
list.stream()
    .filter(x -> {
        System.out.println(x);
        return x > 10;
    });
 

20. 실행 결과?

아무것도 출력 안 됨
 

왜냐하면:

최종 연산 없음
 

이기 때문.


21. 최종 연산(Terminal Operation)

대표:

  • forEach
  • collect
  • count
  • reduce
  • toList

22. 최종 연산 등장 시

그제서야:

Pipeline 실행 시작
 

됩니다.


23. 이것이 Stream Pipeline

매우 중요.

데이터
↓
filter
↓
map
↓
collect
 

연결 구조.


24. filter()

대표 중간 연산.


25. 의미

조건 기반 필터링
 

26. 예시

 
.filter(x -> x > 10)
 

27. 내부적으로 Predicate 사용

즉:

boolean 반환 함수
 

사용.


28. map()

매우 중요.


29. 의미

데이터 변환(transform)
 

입니다.


30. 예시

 
.map(x -> x * 2)
 

31. 내부적으로 Function 사용

입력 → 출력 변환
 

수행.


32. forEach()

최종 연산.


33. 의미

데이터 소비
 

입니다.


34. 내부적으로 Consumer 사용

입력 소비
반환 없음
 

35. collect()

실무에서 매우 중요.

예:

 
.collect(Collectors.toList())
 

36. 의미

결과 수집
 

입니다.


37. reduce()

함수형 핵심 연산.


38. 예시

 
int sum =
    list.stream()
        .reduce(0, (a, b) -> a + b);
 

39. 의미

누적 계산
 

입니다.


40. 내부 반복(Internal Iteration)

매우 중요.

기존 for문:

개발자가 반복 제어
 

외부 반복
 

41. Stream은?

JVM이 반복 제어
 

내부 반복
 

42. 왜 중요할까?

JVM이:

  • 최적화
  • 병렬 처리
  • lazy execution

하기 쉬워짐.


43. 병렬 Stream

예:

 
list.parallelStream()
 

44. 의미

멀티코어 병렬 처리
 

시도.


45. 하지만 주의점 많음

실무에서는:

  • 순서 문제
  • race condition
  • overhead

때문에 무조건 빠르진 않음.


46. Stream 특징


특징 설명
선언형 스타일 O
내부 반복 O
Lazy Evaluation O
함수형 프로그래밍 지원 O

47. Stream은 한 번만 사용 가능

매우 중요.

 
Stream<Integer> s =
    list.stream();

s.count();

s.count();
 

IllegalStateException
 

가능.


48. 왜 그럴까?

Stream은:

일회성 파이프라인
 

이기 때문.


49. Optional과도 연결

예:

 
findFirst()
findAny()
max()
 

는:

Optional 반환
 

가능.


50. 실무에서 자주 하는 실수

1) Stream 과용

복잡한 로직은 가독성 저하.


2) 디버깅 어려움

Pipeline 너무 길어지면 힘듦.


3) 병렬 Stream 남용

오히려 느려질 수 있음.


4) side effect 발생

람다 내부 상태 변경 주의.


51. side effect 예시

안 좋은 예:

 
list.stream()
    .forEach(x -> result.add(x));
 

멀티스레드 시 위험 가능.


52. Stream vs for문


항목 for문 Stream
제어 직접 선언형
가독성 단순 반복 강점 데이터 처리 강점
디버깅 쉬움 어려울 수 있음
병렬화 직접 구현 parallel 지원

53. 핵심 흐름 요약

Collection
↓
Stream 생성
↓
중간 연산(filter/map)
↓
최종 연산(collect/reduce)
↓
실행
 

54. 가장 중요한 핵심 한 줄

Stream은
“데이터를 선언형·함수형 방식으로 처리하기 위한 파이프라인 API”
 

입니다.


55. 정리

Stream API는 단순 for문 대체 문법이 아닙니다.

실제로는:

  • 함수형 프로그래밍
  • Lambda
  • Lazy Evaluation
  • Pipeline
  • 내부 반복
  • 병렬 처리

전체와 연결되는 Java 8 이후 핵심 기능입니다.

특히 실무에서는:

  • map/filter/reduce
  • 내부 반복
  • side effect 주의
  • parallelStream 사용 기준
  • Stream 가독성 관리

를 정확히 이해하는 것이 매우 중요합니다.

다음 글에서는:

Stream 중간 연산 / 최종 연산

을 lazy evaluation 내부 동작, short-circuit, stateful/stateless 연산, pipeline 최적화까지 포함해서 깊게 정리해보겠습니다.

반응형

댓글