스트림이란 무엇인가?
스트림 API의 특징
- 선언형: 더 간결하고 가독성 증가
- 조립할 수 있음: 유연성 증가
- 병렬화: 성능이 좋아진다(parallelStream() 사용)
스트림 시작하기
스트림: 데이터 처리 연산을 지원하도록 소스에서 추출된 연속된 요소
- 연속된 요소: filter, sorted, map과 같은 계산식이 연속됨
- 소스: 외부 데이터 소스로부터 데이터를 소비하는데 이때 순서가 유지된다
- 데이터 처리 연산: DB에서 지원하는 연산과 비슷한 기능을 제공하며 해당 연산을 순차적으로 또는 병렬로 실행 가능
스트림 특징
- 파이프라이닝: 연산끼리 연결하여 커다란 파이프라인 구축 가능
- 내부 반복: 반복자를 이용하지 않아도 내부 반복이 가능
스트림에 사용되는 연산
- filter: 람다를 인수로 받아 스트림에서 특정 요소를 제외
- map: 람다를 이용해서 한 요소를 다른 요소로 변환하거나 정보를 추출
- limit: 정해진 개수 이상의 요소가 스트림에 저장되지 못하게 크기를 축소
- collect: 스트림을 다른 형식으로 변환
스트림과 컬랙션
데이터를 언제 계산하는가가 컬랙션과 스트림의 가장 큰 차이
컬랙션: 컬랙션에 추가하기 전에 계산(DVD에서 로드한 영화는 전부 메모리에 태운 후 재생)
스트림: 요청할 때만 요소를 계산(넷플릭스에서 영화 스트림하는거처럼 영화 일부만 로드, 해당 로드를 반복)
스트림도 딱 한번만 탐색이 가능!
탐색 후 스트림 요소는 소비되며 해당 요소를 다시 탐색하려면 초기 데이터 소스에서 새로운 스트림을 만들어야 한다.
외부 반복과 내부 반복
스트림은 내부 반복이 가능
내부 반복의 장점
- 병렬처리
- 최적화된 순서로 처리 가능

스트림 연산
- 중간 연산: 파이프라인 형성(filter, map, limit)
- 최종 연산: 파이프라인 실행 후 닫는 역할(collect)
중간 연산
Lazy: 스트림 파이프라인에 실행하기 전까지 아무 연산도 실행하지 않음
Lazy 특성 1: 최적화 효과를 얻을 수 있다
Lazy 특성 2: 다른 중간 연산자가 한가지로 병합(루프 퓨전)
최종 연산
스트림 파이프라인에서 결과를 도출(보통 List, Integer, void)
스트림 이용하기
- 질의를 수행할 데이터 소스
- 파이프라인을 구성할 중간 연산 연결
- 파이프라인 실행하고 결과를 만들 최종 연산
스트림 파이프라인은 빌더패턴과 유사