본문 바로가기
모던자바

모던 자바 인 액션 - 5장 마무리

by 임동무 2022. 12. 7.

5장에서는 Stream 의 파이프라인을 구축하는 법 부터 여러 연산에 활용하는 법에 대해 다룬다.

 

stream 연산의 파이프라인은 기본적으로

소스 -> 중간연산 -> 최종연산의 형태로 구성된다.

 

소스는 Stream 의 대상이 되는 각 요소들을 포함하는 데이터를 의미한다.

 

중간연산은 각 요소에 대한 연산들을 의미하며 반환값은 Stream<T> 의 형태를 갖는다.

 

최종연산은 Stream의 결과값에 대한 연산을 의미한다. 

대표적으로 forEach(), collect() 등의 연산이 있다. 

 

 


 

이러한 스트림 연산을 필터링하거나 자를때에는

filter(), takeWhile(), dropWhile(), distinct(), skip(), limit() 의 메서드를 이용할 수 있다. 

 

또한 소스가 정렬되어 있는 상태에서 takeWhile(), dropWhile() 을 이용한다면 요소의 범위를 설정하여 stream 을 더욱 효과적으로 사용할 수 있다.

 

스트림의 요소를 추출하거나 변환할 때에는 map(), flatMap() 을 사용할 수 있다.

이 때, map() 은 stream<T> 를 파라미터로 stream<R> 의 반환값을 가지며

flatMap() 반복된 맵 연산으로 stream<stream<>> 의 반환값을 stream<> 의 반환값을 갖도록 평면화해주는 기능을 한다.

 

filter() 를 통해 필터링된 요소에서 findFirst(), findAny() 메서드로 스트림의 요소를 검색할 수 있다. 

allMatch() , noneMatch(), anyMatch 메서드를 이용하면

주어진 프레디케이트(주어지는 조건)와 일치하는 요소를 스트림에서 검색할 수 있다.

 

모든 요소를 탐색하고 싶지 않고 어떤 값을 기준으로 stream 을 빠져나오고 싶다면 쇼트서킷을 이용하면 된다.

쇼트서킷은 결과를 찾는 즉시 반환하며 스트림을 탈출하는 것을 말한다. 그렇기 때문에 스트림의 모든 요소를 처리하지 않는다.

 


 

스트림의 모든 요소를 반복 조합하며 값을 도출할 때에는 reduce() 연산을 활용하면 된다.

reduce(Math::max) 는 스트림 소스의 최대값, reduce(Integer::sum) 은 합계 등을 계산한다.

 

또한 reduce() 연산은 filter(), map() 연산과는 다르게 모든 요소를 반복, 조합하기 때문에 상태의 저장이 필요하다.

즉, 연산 과정 내에서 결과들이 누적되며 마지막에 연산에 대한 결과를 반환한다. 

sorted(), distinct() 등의 메서드 또한 기존의 값에 대한 정보가 필요하기 때문에 상태의 저장이 필요하다.

그렇기 때문에 상태 있는 연산 stateful operation 이다.

 

하지만 filter(), map() 등의 상태를 저장할 필요가 없기 때문에 상태를 저장하지 않는 stateless operation 이다. 

 


기본형에 대한 stream 을 이용할 때에는 기본형 특화스트림을 사용할 수 있다. 

IntStream, DoubleStream, LongStream 등이 있으며 각각의 특화 스트림은 각 기본형에 특화되어 있다. 

또한 연산에서 사용되는 메서드들 또한 각각의 기본형 특화스트림의 반환값을 가지기 때문에 이에 주의하여 사용해야 하며

이를 피하기 위해서는 박싱과정을 거쳐야한다.

 

컬렉션 뿐만 아니라 int형 배열, 파일 등도 마찬가지로 iterate(), generate() 등의 메서드로 스트림을 만들 수 있으며 이 두 메서드는 무한한 개수의 요소를 가진 무한 스트림이다. 따라서 limit() 연산과 같이 쓰인다.

댓글