자바/스트림

스트림의 최종 연산(조건 검사, 통계, 리듀싱)

백_곰 2022. 4. 15. 13:05

1. forEach()

- peek()와 달리 스트림의 요소를 소모하는 최종연산자이다.

 

void forEach(Consumer<? super T> action)

 

 

 

 

2. 조건 검사 - allMatch(), anyMatch(), noneMatch(), findFirst(), findAny()

- 조건 검사 메서드들은 매개변수로 Predicate를 요구하며, boolean을 반환한다.

 

(1) boolean allMatch (Predicate<? super T> predicate)

(2) boolean anyMatch (Predicate<? super T> predicate)

(3) boolean noneMatch (Predicate<? super T> predicate)

 

 

( 예를 들어, 학생들 총점이 담겨져 있는 stuStream있다고 하자. )

( 이 스트림에 총점이 100 이하인 학생이 있는지 확인하는 코드는 아래와 같이 쓴다. )

 

boolean noFailed = stuStream.anyMatch(s -> s.getTotalScore() <= 100);

 

 

( 이 외에도 findFirst()를 사용하여 조건에 일치하는 첫번째 요소를 반환한다. )
( 주로 filter() 메서드와 함께 쓰인다. )

( 만약 병렬 스트림이라면, findFirst()가 아닌 findAny()를 사용해야 한다. )

 

Optional<Student> stu1 = stuStream.filter(s -> s.getTotalScore() <= 100).findFirst();

Optional<Student> stu2 = ParallelStream.filter(s -> s.getTotalScore() <= 100).findAny();

 

( findAny()findFirst()의 반환 타입은 Optional<T>이다. )

( 만약 스트림의 요소가 없을 때에는 비어있는 Optional 객체를 반환한다. )

 

 

 

 

3. 통계 - count(), sum(), average(), max(), min()

- IntStream과 같은 기본형 스트림에는 스트림의 요소들에 대한 통계 정보를 얻을 수 있는

메서드들이 있다.

 

 

- 그러나, 기본형 스트림이 아닌 경우에는 아래의 메서드 3개 뿐이다.

 

(1) long count()

(2) Optional<T> max(Comparator<? super T> comparator)

(3) Optional<T> min(Comparator<? super T> comparator)

 

 

 

 

4. 리듀싱 - reduce()

- reduce() 메서드는 스트림의 요소를 줄여나가면서 연산을 수행하고 최종결과를 반환한다.

그러므로, 매개변수의 타입은 BinaryOperator<T> 인 것이다.

 

Optional<T> reduce(BinaryOperator<T> accumlator)

 

 

- 이 외에도 연산결과의 초기값(매개변수 identity)을 갖는 reduce()도 있는데, 초기값과 스트림의 첫 번째

요소로 시작한다. 만약 스트림의 요소가 하나도 없는 경우, 초기값이 반환된다.

 

T reduce(T identity, BinaryOperator<T> accumulator)

U reduce(U identity, BiFunction<U,T,U> accumulator, BinaryOperator<U> combiner)

 

 

- 최종 연산 count()sum(), max(), min()은 내부적으로 모두 reduce()를 이용해서 아래와 같이 작성되었다.

 

int count = intStream.reduce(0, (a,b) -> a+1);

int sum = intStream.reduce(0, (a,b) -> a+b);

int max = intStream.reduce(Integer.MIN_VALUE, (a,b) -> a>b ? a:b);

int min = intStream.reduce(Integer.MAX_VALUE, (a,b) -> a<b ? a:b);

 

( 사실 max()min()의 경우, 초기값이 필요없으므로 Optional<T>를 사용하는 것이 낫다. )

( 단, intStream 참조변수의 타입이 IntStream인 경우, OptionalInt를 사용해야 한다. )

( 왜냐하면 IntStream에 정의된 reduce()OptionalInt를 반환하기 때문이다. )

 

OptionalInt max = intStream.reduce((a,b) -> a>b ? a:b);

OptionalInt min = intStream.reduce((a,b) -> a<b ? a:b);

또는

OptionalInt max = intStream.reduce(Integer::max);

OptionalInt min = intStream.reduce(Integer::min);

 

( 또한 OptionalInt에서 값을 꺼낼 때는 아래의 코드처럼 수행하면 된다. )

 

int maxValue = max.getAsInt();

 

 

 

 

5. 위에서 했던 이론을 이해하기 위한 예제(1)