스트림 API

2025. 2. 28. 17:52Java/Java 문법

참고: 자바에서 사용되는 스트림 2가지 

자바에서 스트림은 데이터 흐름을 다루는 개념이며, 크게 두 가지로 나눌 수 있다.  

단어는 같아도 사용 방식은 전혀 다른 개념이므로 헷갈리지 않아야 한다. 

  입출력 스트림 (I/O Stream) 자바 8 스트림 API (Stream API)
사용 파일, 네트워크, 메모리 같은 곳에서
데이터를 주고받는 데 사용
리스트, 배열 같은 컬렉션 데이터를
효율적으로 처리하는 데 사용
목적

데이터 입출력 용도
(순차적 처리)
데이터 가공 및 연산 용도
(함수형 처리)
데이터 형태 바이트, 문자 기반 객체(컬렉션) 기반
방식 파일에서 텍스트 읽기, 소켓 통신 리스트 필터링, 데이터 변환 

 

1. 스트림 API

  • Stream API는 컬렉션(List, Set 등) 데이터를 함수형 스타일로 처리할 수 있도록 도와주는 기능
  • for문 같은 반복문을 쓰지 않고도 데이터를 필터링, 변환, 정렬하는 작업을 간결하게 할 수 있다.
  • 코드를 깔끔하고 직관적으로 만들기 위해 람다 표현식과 메소드 참조 표현식과 함께 사용된다.  
  • 특징
    • 컬렉션을 직접 변경하지 않고 새로운 값을 반환 (읽기 전용) 
    • 내부 반복을 사용해서 코드가 간결하고 가독성이 좋음
    • 병렬 처리(parallelStream())를 활용하면 성능 최적화 가능
    • 스트림은 한번만 사용되고 사라진다. 

 

2. 스트림 API의 활용

스트림 API는 스트림 생성, 가공, 결과의 과정으로 활용된다. 

구분 설명 예제
스트림 생성 컬렉션, 배열 등에서 스트림 만들기 stream(), parallelStream()
중간 연산 데이터 변형 및 가공
(최종 연산이 실행될 때까지 동작X)
filter(), map(), sorted()
최종 연산 결과 반환 forEach(), collect(), count(), reduce()

 

2-1. 스트림 생성 메소드 

  • stream() : 한 개의 스레드가 순서대로 처리하는 순차 처리 스트림을 생성
  • parallelStream() : 여러 개의 스레드가 나눠서 처리하는 병렬 처리 스트림을 생성
    • 스트림을 병렬로 실행하면 속도를 높일 수 있다.
    • 단,  작은 데이터에서는 오히려 성능이 나빠질 수 있음
    • 병렬 스트림은 순서가 보장되지 않으므로 정렬이 중요한 경우엔 피하는 게 좋음

2-2. 중간 연산 메소드 

  • filter() : 조건에 맞는 요소만 추출
  • map() : 데이터를 다른 형태로 변환
  • sorted() : 정렬
  • distinct() : 중복 제거

2-3. 최종 연산 메소드

  • forEach() : 각 요소를 출력하거나 특정 동작 수행
  • collect() : 리스트, 셋 등으로 변환
  • count() : 요소 개수 반환
  • reduce() : 요소를 하나의 값으로 줄이기
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamCreation {
    public static void main(String[] args) {
    	// 리스트에서 스트림 생성
        List<String> list = Arrays.asList("apple", "banana", "avocado", "blueberry");
        Stream<String> stream1 = list.stream();
        Stream<String> parallelStream = list.parallelStream();
        // 배열에서 스트림 생성
        Stream<Integer> stream2 = Arrays.stream(new Integer[]{1, 2, 3, 4, 5});
        // 직접 값으로 스트림 생성
        Stream<String> stream3 = Stream.of("A", "B", "C");
		
        //예시1
        list.stream()
                .filter(s -> s.startsWith("a")) // 'a'로 시작하는 단어만
                .map(String::toUpperCase) // 대문자로 변환
                .sorted() // 정렬
                .forEach(System.out::println); // 최종 연산 APPLE, AVOCADO

        //예시2 
        List<String> filteredList = list.stream()
                .filter(s -> s.startsWith("a"))
                .collect(Collectors.toList());
        System.out.println(filteredList); // [apple, avocado]
	}
}