목차
· Max/Min/Count
· All Match / Any Match
· Find First / Find Any
· Reduce
스트림 정리 1편에서 다뤘듯이 스트림 파이프라인이 있는데 이번 글에서는 종결 처리하는 부분에 대해 다룰 것이다.
Max, Min, Count
Optional<T> max(Comparator<? super T> comparator);
Optional<T> min(Comparator<? super T> comparator);
long count();
max – Stream 안의 데이터 중 최댓값을 반환한다. Stream이 비어있다면 빈 Optional을 반환한다.
min – Stream 안의 데이터 중 최소값을 반환한다. Stream이 비어있다면 빈 Optional을 반환한다.
count – Stream 안의 데이터의 개수를 반환한다.
다음은 max, min, count를 사용한 예시이다.
Optional<Integer> max = Stream.of(50, 30, 60, 20, 10)
.max(Integer::compareTo);
// max.get() = 60
Optional<Integer> min = Stream.of(50, 30, 60, 20, 10)
.min(Integer::compareTo);
System.out.println("min.get() = " + min.get());
// min.get() = 10
long count = Stream.of(50, 30, 60, 20, 10)
.count();
System.out.println("count = " + count);
// count = 5
All Match, Any Match
boolean allMatch(Predicate<? super T> predicate);
boolean anyMatch(Predicate<? super T> predicate);
allMatch – Stream 안의 모든 데이터가 predicate을 만족하면 true를 반환한다.
anyMatch – Stream 안의 데이터 중 하나라도 predicate을 만족하면 true를 반환한다.
다음은 allMatch, anyMatch를 사용한 예시이다.
List<Integer> numbers = Arrays.asList(3, -4, 2, 7, 9);
boolean allMatch = numbers.stream()
.allMatch(number -> number > 0);
System.out.println("allMatch = " + allMatch);
// allMatch = false
boolean anyMatch = numbers.stream().anyMatch(number -> number < 0);
System.out.println("anyMatch = " + anyMatch);
// anyMatch = true
Find First, Find Any
Optional<T> findFirst();
Optional<T> findAny();
findFirst – Stream 안의 첫번째 데이터를 반환한다.. Stream이 비어있다면 비어있는 Optional을 반환한다.
findAny – Stream 안의 아무 데이터나 리턴한다. 마찬가지로 Stream이 비어있다면 빈 Optional을 반환한다.
다음은 findFirst, findAny를 사용한 예시이다.
Optional<Integer> anyNegativeInteger = Stream.of(3, 2, -5, 6)
.filter(x -> x < 0)
.findAny();
System.out.println("anyNegativeInteger.get() = " + anyNegativeInteger.get());
// anyNegativeInteger.get() = -5
Optional<Integer> findPositiveInteger = Stream.of(3, 2, -5, 6)
.filter(x -> x > 0)
.findFirst();
System.out.println("findPositiveInteger.get() = " + findPositiveInteger.get());
//findPositiveInteger.get() = 3
Reduce
주어진 함수를 반복 적용해 Stream 안의 데이터를 하나의 값으로 합치는 작업이다.
Optional<T> reduce(BinaryOperator<T> accumulator);
T reduce(T identity, BinaryOperator<T> accumulator);
<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
reduce 1 – 주어진 accumulator를 이용해 데이터를 합친다. Stream이 비어있을 경우 빈 Optional을 반환한다.
BinaryOperator는 Type T의 인자 두 개를 받고, 동일한 Type T 객체를 리턴하는 함수형 인터페이스이다.
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
}
reduce 2 – 주어진 초기값과 accumulator를 이용. identity라는 초기값이 있기 때문에 항상 반환 값이 존재한다.
reduce 3 – 합치는 과정에서 타입이 바뀔 경우 사용. Map + reduce로 대체 가능하다.
다음은 BinaryOperator 인터페이스만 매개변수로 가지는 reduce의 예시이다.
List<Integer> numbers = Arrays.asList(1, 4, -2, -5, 3);
Integer sum = numbers.stream()
.reduce((x, y) -> x + y)
.get();
System.out.println("sum = " + sum);
// sum = 1
다음은 초기값과 BinaryOperator 인터페이스를 매개변수로 가지는 reduce의 예시이다.
List<String> numStrList = Arrays.asList("3", "2", "5", "-4");
Integer sumOfNumberStrList = numStrList.stream()
.map(Integer::parseInt)
.reduce(0, (x, y) -> x + y);
System.out.println("sumOfNumberStrList = " + sumOfNumberStrList);
// sumOfNumberStrList = 6
심화로 회원들이 주문한 총 금액을 구할 때 어떻게 reduce를 사용하는지 확인해보자
ArrayList<Order> firstOrders = new ArrayList<>();
firstOrders.add(new Order(BigDecimal.valueOf(1000)));
firstOrders.add(new Order(BigDecimal.valueOf(2000)));
ArrayList<Order> twoOrders = new ArrayList<>();
twoOrders.add(new Order(BigDecimal.valueOf(3000)));
twoOrders.add(new Order(BigDecimal.valueOf(4000)));
ArrayList<Order> threeOrders = new ArrayList<>();
threeOrders.add(new Order(BigDecimal.valueOf(5000)));
threeOrders.add(new Order(BigDecimal.valueOf(6000)));
List<Member> members = new ArrayList<>();
members.add(new Member("Kim", 20, false, firstOrders));
members.add(new Member("An", 40, true, twoOrders));
members.add(new Member("Oh", 60, false, threeOrders));
BigDecimal amountSum = members.stream() // Stream<Member>
.map(Member::getOrders) // Stream<List<Order>>
.flatMap(List::stream) // Stream<Order>
.map(Order::getAmount) // Stream<BigDecimal>
.reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("amountSum = " + amountSum);
// amountSum = 21000
'Language > Java' 카테고리의 다른 글
Java 스트림 (Stream) 사용법 및 정리 3/3 (Collectors, Grouping By ..) (0) | 2022.10.10 |
---|---|
Java 스트림 (Stream) 사용법 및 정리 1/3 (Map, Filter, FlatMap ..) (0) | 2022.10.09 |
Java 메서드 참조란? (0) | 2022.10.09 |
Java 8 함수형 인터페이스 이해하기 (0) | 2022.10.08 |
Java 람다 표현식과 Function Interface (0) | 2022.10.08 |