Java 8 스트림(Stream) API란?
Java 8에서 도입된 스트림(Stream)은 데이터 집합을 처리하기 위한 기능으로, 요소를 저장하는 용도가 아닙니다. 스트림은 원본 컬렉션을 수정하지 않으며, 파이프라인으로 연결된 메서드에 따라 처리 결과만 제공합니다.
스트림 API는 다양한 연산을 지원하며, 이러한 연산은 크게 두 가지로 나눌 수 있습니다.
1. 중간 연산(Intermediate Operation)
- 다른 메서드를 파이프라인으로 연결하고, 하나의 스트림을 다른 스트림으로 변환하는 데 사용됩니다.
- 최종 연산이 실행되기 전까지는 실제로 동작하지 않기 때문에(지연 평가) 즉각적인 결과를 생성하지 않습니다.
- 대표적인 예시:
sorted(Comparator<T>),peek(Consumer<T>),distinct()
2. 최종 연산(Terminal Operation)
- 스트림 파이프라인의 마지막 단계에서 실제 결과를 생성하는 연산입니다.
- 다른 메서드와 체이닝(chaining)하여 이어갈 수 없습니다.
- 대표적인 예시:
forEach,count,toArray
중간 연산 vs 최종 연산 비교
| 번호 | 구분 | 중간 연산(Intermediate) | 최종 연산(Terminal) |
|---|---|---|---|
| 1 | 기본 개념 | 다른 메서드를 파이프라인으로 연결하고 스트림을 다른 스트림으로 변환하는 데 사용됩니다. | 스트림에 적용되는 마지막 단계의 메서드입니다. |
| 2 | 반환 타입 | 항상 또 다른 스트림을 반환합니다. | 최종 결과값을 반환합니다. |
| 3 | 주요 메서드 | sorted(Comparator<T>), peek(Consumer<T>), distinct() | forEach, count, toArray |
| 4 | 사용 사례 | 스트림을 다른 형태의 스트림으로 변환할 때 사용합니다. | 파이프라인의 실제 결과를 도출할 때 사용합니다. |
중간 연산과 최종 연산 예제
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String args[]) {
List<String> laptopList = new ArrayList<>();
laptopList.add("DELL");
laptopList.add("ACER");
laptopList.add("HCL");
// 중간 연산: sorted() - 정렬된 새 스트림을 반환
laptopList.stream()
.sorted()
// 최종 연산: forEach() - 실제 결과를 출력
.forEach(a -> System.out.println(a));
}
}위 예제처럼 중간 연산인 sorted()는 스트림을 변환만 할 뿐 즉시 실행되지 않고, 최종 연산인 forEach()가 호출되는 시점에 비로소 전체 파이프라인이 실행되어 정렬된 결과가 출력됩니다. 이러한 지연 평가(Lazy Evaluation) 방식 덕분에 불필요한 연산을 줄여 성능을 최적화할 수 있습니다.