🏃♂️ 들어가기 앞서..
본 게시물은 스터디 활동 중에 작성한 게시물로 자바의 정석-기초편 교재를 학습하여 정리하는 글입니다.
※ 스터디 Page : 〔투 비 마스터 : 자바〕
*해당 교재의 목차 순서와 구성을 참고하여 작성하며
각 내용마다 부족할 수 있는 내용이나 개인적으로 궁금한 점은
추가적인 검색을 통해 채워나갈 예정입니다.
최종 연산은
직전에 알아봤었던 중간연산과는 다르게
스트림 당 단 1번만 사용할 수 있다.
최종 연산은 스트림을 소모해서 결과를 만들어내기 때문에
최종 연산 후에는
스트림이 닫히게 되고 사용할 수 없게 되는 것이다.
반환값
즉, 결과는
중간연산과 같은 스트림이 아닌
" 단일 값 "(int
, boolean
등) 이거나
스트림의 요소가 담긴 " 배열 / 컬렉션 "일 수 있다.
forEach()
스트림 단원을 공부하면서 꽤 많이 본 최종 연산 메서드일 것이다.
각 요소에 적용시키는 함수를 매개변수로 받는데
이전 중간 연산 메서드 중 " 중간 결과를 확인하는 peek()
" 와는 달리
forEach()
는 스트림을 소모하는 최종 연산으로
반환 타입은 void
이며
주로 forEach(System.out::print)
등과 같이
요소 출력의 용도로 많이 쓰인다.
forEachOrdered()
병렬 스트림의 경우, " 순서보장 " _ 스트림을
parallel()
로 처리할 때
void forEach( Consumer<? super T> action )
void forEachOrdered( Consumer<? super T> action )
말그대로 매개변수로 들어온 조건식에 대한 검사 결과를 반환하는 메서드들로
boolean allMatch( Predicate<? super T> Predicate )
boolean anyMatch( Predicate<? super T> Predicate )
boolean noneMatch( Predicate<? super T> Predicate ) // <-> allMatch
allMatch()
: 모든 요소 만족 → true
anyMatch()
: 하나라도 요소 만족 → true
noneMatch()
: 모든 요소 불만족 → true
이 3가지 메서드가 있다.
주로 Stream의 중간 연산인 filter()
와 함께 사용되는데
" 조건에 일치하는 첫 번째 요소 "를 반환하는 findFirst()
와
" 조건에 일치하는 아무거나 요소 하나 "를 반환하는 findAny()
가 있다.
첫번째의 의의를 두는 findFirst()
는
" 직렬 스트림(sequential()
) "에서 쓰이고
순서 관련없이 병렬로 처리하는
" 병렬 스트림(parallel()
) "에서 findAny()
가 쓰인다.
// Optional<Student> stuStream
Optional<Student> result = stuStream.filter( s -> s.getTotalScore() <= 100).findFirst();
Optional<Student> result = stuStream.parallel().filter( s -> s.getTotalScore() <= 100).findAny();
reduce()
스트림의 요소를 하나씩 줄여가며 " 누적연산 (accumulate)"을 수행한다.
※BinaryOperator<T>
--(extends)-->BiFunction<U,T,U>
상속관계
-> 결국,BinaryOperator<T>
==BiFunction<T,T,T>
- 매개변수 :
BinaryOperator<T> accumulator
이 reduce()
메서드는 다양한 형태로
오버로딩이 되어있다.
//기본적
Optional<T> reduce( BinaryOperator<T> accumulator )
/*
- identity : 초기값
- accumulator : 이전 연산 결과 & 스트림 요소에 수행할 연산
- combiner : (병렬 스트림) 결과를 "합치는데 사용"할 연산
*/
// ★ 핵심
T reduce( T identity, BinaryOperator<T> accumulator )
// 입력값 2개 받는 BinaryFunction F.I의 연산 ->
// combiner -> 합치기 연산
U reduce( U identity, BiFunction<U, T, U> accumulator, BinaryOperator<U> combiner )
사실 Optional<T> reduce()
와 T reduce()
는
같은 것이지만
Optional<T> reduce()
에 " 매개변수 identity
가 없는 이유 "는
만약 비어있는 스트림일 경우엔
T reduce()
는 초기값이 없을 때, identity
값을 반환하게 때문에 괜찮다.
그렇기 때문에 반환타입이 identity의 타입과 동일하고
하지만 초기값 지정이 없다면
null이 반환될 수가 있다.
그렇기 때문에 Optional<T>
로 반환하게 되는 것이다.
따라서 " identity 매개변수를 입력하지 않을 경우 "
《결과를 담을 참조변수》의 타입은 Optional
로 지정해주어야한다.
실제로 스트림 최종 연산 메서드들(아래 참고) 중
여러 값들을 누적 or 차례대로 계산해서 결과를 반환하는
count()
, sum()
, max()
, min()
과 같은 메서드들도
자세히 살펴보면
모두 reduce()
메서드를 통한 연산을 활용하는 구조이다.
🔆 최종 연산 메서드 모음 🔆
※collect()
나Collector
내용 : [JAVA] 람다와 스트림 ( Lambda & Stream ) ⑪ 글 참고
중간 연산 설명 void forEach( Consumer<? super T> action )
void forEachOrdered( Consumer<? super T> action )
: 순서 유지 _ 병렬 스트림 처리 시에 주로 이용각 요소에 지정된 작업 수행 long count()
스트림 요소 개수 Optional<T> max( Comparator<T> comparator )
Optional<T> min( Comparator<T> comparator )
최대 / 최솟값 Optional<T> findAny()
: 아무거나 하나 _ 병렬 -filter()
와 자주 사용
Optional<T> findFirst()
: 첫번째 요소 - 직렬스트림의 요소 하나 반환 boolean allMatch( Predicate<T> p )
: 모두 만족
boolean anyMatch( Predicate<T> p )
: 하나라도 만족
boolean noneMatch( Predicate<T> p )
: 모두 만족 X모든 요소가 주어진 조건 만족 여부 확인 Object[] toArray()
A[] toArray( IntFinction<A[]> generator )
스티림 요소 → 배열 반환 《 핵 심 》 Optional<T> reduce( BinaryOperator<T> accumulator )
T reduce( T identity, BinaryOperator<T> accumulator )
U reduce( U identity, BiFunction<U, T, U> accumulator, BinaryOperator<U> combiner )
요소를 하나씩 줄여가면서(Reducing) 계산 R collect( Collector<T, A, R> collector )
R collect( Supplier<R> supplier, BiConsumer<R, T> accumulator, BiConsumer<R, R> combiner )
스트림 요소 수집
*주로 그룹화 / 분할 결과 컬렉션에 담아 반환할 때 싸용