스트림은 Java 8 API 에 새로 추가된 기능
선언형으로 컬렉션 데이터를 처리할 수 있음
멀티쓰레드 코드를 구현하지 않아도 데이터를 투명하게 병렬로 처리가능
filter
, sorted
, map
, collect
같은 여러 빌딩 블록 연산을 연결해서 복잡한 데이터 처리 파이프 라인을 만들 수 있음.
즉 스트림의 키워드를 정리하자면 다음과 같다. 선언형
, 조립
, 병렬화
filter
,map
,reduce
,find
,match
,sort
등으로 데이터를 조작할 수 있다.스트림은 filter,map,limit,collect로 이어지는 일련의 데이터 처리 연산을 적용.
collect
를 제외한 모든 연산은 서로 파이프라인을 형성할 수 있도록 스트림을 반환한다.마지막으로 collect 연산으로 파이프라인을 처리해서 결과를 반환한다. 마지막에 collect가 호출되기 전까지는 메소드 호출이 저장되는 효과가 있다.
스트림과 컬렉션의 가장 큰 차이는 데이터를 언제 계산 하느냐가 가장 큰 차이점이다.
컬렉션은 현재 자료구조가 포함하는 모든 값을 메모리에 저장하는 자료구조다. 즉 컬렉션의 모든 요소는 컬렉션에 추가하기 전에 계산되어져야 한다.
반면 스트림은 이론적으로 요청할때만 요소를 계산하는 고정된 자료구조다.
결과적으로 스트림은 생산자와 소비자의 관계를 형성한다.
스트림과 컬렉션의 철학적으로 생각해보자면?
스트림은 시간적으로 흩어진 값의 집합으로 간주할 수 있다.
반면 컬렉션은 특정시간에 모든 것이 존재하는 공간에 흩어진 값으로 비유할 수 있다.
외부반복 | 내부반복 | |
---|---|---|
투명성 | X | O |
병렬처리 | 어려움(직접 관리) | 쉬움(자동 처리) |
filter
,map
,limit
은 서로 연결되어 파이프라인을 형성한다. 이를 중간 연산이라한다.collect
로 파이프라인을 실행한 다음에 닫는다. 스트림을 닫는 연산을 최종 연산 이라고 한다.filter
와 sorted
같은 중간 연산은 다른 스트림을 반환한다.
중간 연산의 가장 중요한 특징은 단말 연산을 스트림 파이프라인에 실행하기전 까지는 아무 연산도 수행하지 않는다는 것
= Lazy한 연산.
이런 스트림의 특성 덕에 몇가지 최적효과를 얻을 수 있다. => short circit
Short Circuit이란? 연산을 모두 수행하지 않고 검색 조건을 만족했을시, 즉시 이후 연산을 종료하고 결과를 반환하는 기법
List
, Integer
, void
등 스트림 이외의 결과반환연산 | 형식 | 반환형식 | 연산의 인수 | 함수 디스크립터 |
---|---|---|---|---|
filter | 중간 연산 | Stream<T> | Predicate<T> | T -> boolean |
map | 중간 연산 | Stream<R> | Function<T,R> | T -> R |
limit | 중간 연산 | Stream<T> | ||
sorted | 중간 연산 | Stream<T> | Comparator<T> | (T,T)-> int |
distinct | 중간 연산 | Stream<T> |
연산 | 형식 | 반환 형식 | 목적 |
---|---|---|---|
forEach | 최종 연산 | void | 스트림의 각 요소를 소비하면서 람다를 적용한다. |
count | 최종 연산 | Long(generic) | 스트림의 요소 개수를 반환한다. |
collect | 최종연산 | 스트림을 리듀스해서 리스트, 맵, 정수형식의 컬렉션을 만든다. |