Stream을 사용하다가 reduce()
와 파라미터들에 대해 스스로 이해가 부족하다고 느껴 다시 한 번 정리한다.
BinaryOperator
Represents an operation upon two operands of the same type, producing a result of the same type as the operands. This is a specialization of BiFunction for the case where the operands and the result are all of the same type.
BinaryOperator
는 같은 타입의 파라미터 2개를 받아 결과값을 리턴하는 functional interface
다. 주로 람다
와 메서드 참조
를 위해 사용된다. 그냥 식을 적는 것보다 가독성이 좋기 때문에 적극 활용하는 것이 좋다.
또한, BiFunction
을 상속하는 인터페이스로서, apply(T t, U u)
메서드를 호출해서 function
을 적용한다.
IntBinaryOperator
IntBinaryOperator
는 int
타입의 파라미터 2개를 받아 int
타입의 결과값을 리턴한다.
이름에서 알 수 있듯이 BinaryOperator
를 상속하며, applyAsInt(int left, int right)
는 내부적으로 BiFunction
의 apply(T t, U u)
를 호출한다.
아래 reduce()
설명 예시는 모두 IntStream
과 IntBinaryOperator
를 사용했다.
reduce()
우선, reduce()
는 스트림의 원소들을 하나씩 소모해가며, 누적 계산을 수행하고 결과값을 리턴하는 메서드다.
reduce()
는 파라미터를 3개 받을 수 있다.
T identity
: 계산에 적용할 초깃값으로, 스트림이 비어 있더라도 초깃값을 반환BinaryOperator<T> accumulator
: 적용할 계산 함수BinaryOperator<U> combiner
: 병렬 스트림에서 각 쓰레드 계산 결과를 합치는 함수Optional<T> reduce(BinaryOperator<T> accumulator)
아래와 같이 스트림의 모든 element
를 차례로 돌면서 accumulator
를 적용하며 result
를 갱신한다.
스트림이 비어 있으면 Optional.empty()
를 반환한다.
boolean foundAny = false;
T result = null;
for (T element : this stream) {
if (!foundAny) {
foundAny = true;
result = element;
} else
result = accumulator.apply(result, element);
}
return foundAny ? Optional.of(result) : Optional.empty();
사용 예시는 아래와 같다.
OptionalInt result = IntStream.of(1, 2, 3)
.mapToInt(value -> value + 1)
.reduce((a,b) -> a+b);
result.getAsInt(); // 6
T reduce(T identity, BinaryOperator<T> accumulator)
결과의 초깃값을 identity
로 설정한 후, 스트림의 모든 element
를 차례로 돌면서 accumulator
를 적용하며 result
를 갱신한다.
스트림이 비어 있어도 초깃값인 identity
를 반환한다.
T result = identity;
for (T element : this stream)
result = accumulator.apply(result, element)
return result;
사용 예시는 아래와 같다.
int result = IntStream.of(3, 4, 5)
.reduce(1, (a,b) -> a*b); // 60
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
U result = identity;
for (T element : this stream)
result = accumulator.apply(result, element)
return result;
(수정필요)
안녕하세요. 글 보다가 잘못된 내용이 있어서 댓글 남깁니다.
OptionalInt result = IntStream.of(1, 2, 3)
.mapToInt(value -> value + 1)
.reduce((a,b) -> a+b);
result.getAsInt(); // 6
OptionalInt result = IntStream.of(1, 2, 3).boxed()
.mapToInt(value -> value + 1)
.reduce((a,b) -> a+b);