스트림 API가 제공하는 추상 개념 중 핵심은 두 가지다.
스트림 파이프라인은 소스 스트림에서 시작해 종단 연산으로 끝나며, 그 사이에 하나 이상의 중간 연산이 있을 수 있다.
중간 연산들은 모두 한 스틀미을 다른 스트림으로 변환하는데, 변환된 스트림의 원소 타입은 변화전 스트림의 원소 타입과 같을 수도 다를 수도 있다. 종단 연산은 원소를 정렬해 컬렉션에 담거나, 특정 원소 하나를 선택하거나, 모든 원소를 출력하는 식이다.
스트림 파이프라인은 지연 평가(lazy evaluation)된다. 평가는 종단 연산이 호출될 때 이뤄지며, 종단 연산에 쓰이지 않는 데이터 원소는 계산에 쓰이지 않는다. 이러한 지연 평가가 무한 스트림을 다룰 수 있게 해주는 열쇠다.
기본적으로 스트림 파이프라인은 순차적으로 수행된다. 파이프라인을 병렬로 실행하려면 파이프라인을 구성하는 스트림 중 하나에서 paraller 메서드를 호출해주면 되나 효과를 볼 수 있는 상황은 많지 않다(아이템 48)
스트림은 잘 쓰면 프로그램이 짧고 깔끔해지지만, 잘못 사용하면 읽기 어렵고 유지보수도 힘들어진다.
이번 아이템에서 보여준 프로그램에서처럼 스트림 파이프라인은 되풀이되는 계산을 함수 객체(주로 람다나 메서드 참조)로 표현한다. 반면 반복 코드에서는 코드 블록을 이용해 표현한다. 반면 반복 코드에서는 코드 블록을 사용해 표현한다. 그런데 함수 객체로는 할 수 없지만, 코드 블록으로는 할 수있는 일들이 있다.
코드 블록에서는 범위 안의 지역 변수를 일곡 수정할 수 있다. 하지만 람다에서는 final 변수만 읽을 수 있고, 지역변수 수정 불가능하다.
코드 블록에서는 retur, break, continue으로 빠져나갈 수 있지만 람다는 불가능하다.
계산 로직에서 위의 일들을 해야하면 스트림과 맞지 않는 것이다.
반면 아래 일들은 스트림에 안성맞춤이다ㅏ.
스트림으로 또 어려운일은 파이프라인의 여러 단계를 통과할 때 이 데이터의 각 단계에서의 값들에 동시에 접근하기 어려운 경우다.