스트림 API
2025. 2. 28. 17:52ㆍJava/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]
}
}