Skip to content
Woo Jin Jang edited this page Jun 6, 2025 · 5 revisions

📚 스트림 API

  • 스트림(Stream)은 자바 8부터 추가된 기능으로 데이터 흐름을 추상화해서 다루는 도구이다.
  • 컬렉션 또는 배열 등의 요소들을 연산 파이프라인을 통해 연속적인 형태로 다루는 것이다.

❓파이프라인

스트림이 여러 단계를 거쳐 변환되고 처리되는 모습이 마치 물이 여러 파이프를 타고 이동하면서 정수 시설이나 필터를 거치는 과정과 유사하기 때문에 파이프라인이라는 용어를 사용한다.

[스트림의 특징]

  • 데이터 소스를 변경하지 않는다.
    • 스트림에서 제공하는 연산들은 원본 컬렉션을 변경하지 않고 결과만 새로 생성한다.
  • 일회성(1회 소비)
    • 한 번 사용된 스트림은 다시 사용할 수 없으며 필요하다면 새로 스트림을 생성해야 한다.
  • 파이프라인 구성
    • 중간 연산들이 이어지다가 최종 연산을 만나면 연산이 수행되고 종료된다.
  • 지연 연산
    • 중간 연산은 실제로 필요할 때까지 동작하지 않고 최종 연산이 실행될 때 한 번에 처리된다.
  • 병렬
    • 스트림으로부터 병렬 스트림을 쉽게 만들 수 있어 멀티코어 환경에서 병렬 연산을 비교적 단순한 코드로 작성할 수 있다.

📚 지연 연산

  • 스트림 API에서 지연 연산이란, filter, map과 같은 중간 연산들은 toList와 같은 최종 연산이 호출되기 전까지 실제로 실행되지 않는다는 의미이다.
  • 즉, 중간 연산들은 결과를 바로 계산하지 않고, "무엇을 해야할지"에 대한 설정만을 저장해둔다.
  • 그리고 최종 연산이 실행되는 그 순간, 그때서야 중간 연산이 순차적으로 한 번에 수행된다.
  • 불필요한 연산 생략 가능
    • findFirst(), limit()와 같은 단축 연산을 사용하면 결과를 찾은 시점에서 더 이상 나머지 요소들을 처리할 필요가 없다.
  • 메모리 사용 효율
    • 중간 연산 결과를 매 단계마다 별도 자료구조에 저장하지 않고 최종 연산 때까지 필요할 때만 가져와서 처리한다.
  • 파이프라인 최적화
    • 스트림은 요소를 하나씩 꺼내면서 연산을 묶어서 실행할 수 있다.
    • 이렇게 하면 메모리를 절약할 수 있고 짜잘짜잘하게 중간 단계마다 저장하지 않아도 되므로 내부적으로 효율적으로 동작하게 된다.

📚 스트림 생성

  • 스트림은 자바 8부터 추가된 기능으로 데이터 처리에 있어서 간결하고 효율적인 코드 작성을 가능하게 해준다.
  • 스트림을 이용하면 반복문(외부 반복)없이도 간단하게 필터링, 정렬, 변환 등의 작업을 적용할 수 있다.
  • 특히 스트림은 중간 연산과 최종 연산을 구분하며, 지연 연산을 통해 불필요한 연산을 최소화한다.
생성 방법 코드 예시 특징
컬렉션 list.stream() List,Set등 컬렉션에서 스트림을 생성
배열 Arrays.stream(arr) 배열에서 스트림을 생성
Stream.of() Stream.of("a", "b", "c") 직접 요소를 입력해 스트림을 생성
무한 스트림(iterate) Stream.iterate(0, n -> n + 2) 무한 스트림 생성(초기값 + 함수)
무한 스트림(generate) Stream.generate(Math::random) 무한 스트림 생성(함수형 인터페이스 사용)

📚 중간 연산

연산 설명
filter 조건에 맞는 요소만을 남김
map 요소를 다른 형태로 변환
flatMap 중첩 구조 스트림을 일차원으로 평탄화
distinct 중복 요소 제거
sorted 요소 정렬
peek 중간 처리(로그, 디버깅)
limit 앞에서 N개의 요소만 추출
skip 앞에서 N개의 요소를 건너뛰고 이후 요소만 추출
takeWhile 조건을 만족하는 동안 요소 추출
dropWhile 조건을 만족하는 동안 요소를 버리고 이후 요소를 추출
  • 중간 연산은 파이프라인 형태로 연결할 수 있으며, 스트림을 변경하지만 원본 데이터 자체를 변경하지 않는다.
  • 중간 연산은 lazy하게 동작하므로 최종 연산이 실행될 때까지는 실제 처리가 일어나지 않는다.
  • peek은 디버깅을 목적으로 자주 사용하며 실제 스트림 요소값을 변경하거나 연산 결과를 반환하지 않는다.
  • takeWhile, dropWhile은 정렬된 스트림에서 사용할 때 유용하다.

📚 FlatMap

  • 각 요소를 스트림으로 변환한 뒤, 그 결과를 하나의 스트림으로 평탄화해준다.
# Before
[
  [1, 2],
  [3, 4],
  [5, 6],
]
# After
[1, 2, 3, 4, 5, 6]

📚 최종 연산

연산 설명 특징
collect Collector를 사용하여 결과 수집(다양한 형태로 변환 가능) stream.collect(Collectors.toList())
toList() 스트림을 불변 데이터로 수집 stream.toList()
toArray 스트림을 배열로 변환 stream.toArray(Integer[]::new)
forEach 각 요소에 대해 동작 수행 stream.forEach()
count 요소 개수 반환 stream.count()
reduce 누적 함수를 사용해 모든 요소를 단일 값으로 합침, 초기값이 없다면 Optional로 반환 stream.reduce
min/max 최소값, 최대값을 Optional로 반환 stream.min(), stream.max()
findFirst 조건에 맞는 첫 번째 요소(Optional 반환) stream.findFirst()
findAny 조건에 맞는 아무 요소(Optional 반환) stream.findAny()
anyMatch 하나라도 조건을 만족하는지 stream.anyMatch(n -> n > 5)
``allMatch` 모든 조건을 만족하는지 stream.allMatch(n -> n > 0)
noneMatch 하나도 조건을 만족하지 않는지 stream.noneMatch(n -> n < 0)

📚 기본형 특화 스트림

📚 컬렉터

📚 다운 스트림 컬렉터

📖 Java

📖 Kotlin

📖 Coroutine

📖 Spring

📖 Spring Security

📖 Spring Batch

📖 Reactive Programming

📖 Database

📖 MySQL

📖 Redis

📖 JPA

📖 QueryDsl

📖 MSA

📖 Kafka

📖 Apache Flink

  • [Apache Flink - Apache Flink Architecture]
  • [Apache Flink - Stream Processing]
  • [Apache Flink - Data Stream API & Window]
  • [Apache Flink - State Management]

📖 HTTP

📖 AWS

📖 Docker

📖 Kubernetes

📖 CI/CD

📖 Nginx

📖 Monitoring🥈

  • [Monitoring - Log Concept]
  • [Monitoring - Log Level & Filter]
  • [Monitoring - Logback]
  • [Monitoring - Log Collection with ELK Stack]
  • [Monitoring - Log Monitoring with Kibana]
  • [Monitoring - Building a Monitoring System with Spring Boot Actuator]
  • [Monitoring - Server Monitoring with Prometheus and Grafana with Discord Alerts]

📖 Test

📖 Effective Java 3/E

📖 Kotlin Academy - Effective Kotlin

📖 Kotlin Academy - 핵심편

📖 스프링으로 시작하는 리액티브 프로그래밍

📖 가상 면접 사례로 배우는 대규모 시스템 설계 기초 1

📖 가상 면접 사례로 배우는 대규모 시스템 설계 기초 2

📖 Clean Code

📖 리팩토링 2판

📖 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식

📖 GraphQL

Clone this wiki locally