위로
아래
리듀싱
- 단순 집계(원소 개수, 합계, 평균값) 가 아닌 복잡한 집계를 위하여 사용
- Stream 인터페이스에서 제공하는 람다식을 사용하는 기능.
- 리듀싱 연산은 스트림 원소를 단 하나의 값으로 축약시키는 연산.
- 메소드 종류
- reduce(람다식) : 2개 원소를 조합해서 1개 값으로 축약하는 과정을 반복하여 집계한 결과를 Optional타입으로 반환
- reduce(초기값, 람다식) : 첫 번째 인자가 초기값. 결과도 초기값의 타입을 따라간다.
예시
더보기
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;
public class Reduce1Demo {
public static void main(String[] args) {
List<Integer> number = List.of(3,4,5,1,2);
//3+4, (3+4)+5, ((3+4)+5)+1 이런 식으로 순차적으로 가야할 것을 한 번에 축약해서 쓴다
int sum1 = number.stream().reduce(0,(a,b)->a+b);
int sum2 = number.stream().reduce(0, Integer::sum);
int mul1 = number.stream().reduce(0, (a,b) -> a*b);
System.out.println(sum1);
System.out.println(sum2);
System.out.println(mul1);
// 초기값이 없는 reduce
Optional<Integer> sum3 = number.stream().reduce(Integer::sum);
//Integer (객체)형인 값을 int로 변경해서 받아라
OptionalInt sum4 = number.stream().mapToInt(x -> x.intValue()).reduce(Integer::sum);
Optional<Integer> mul2 = number.stream().reduce((a,b)->a*b);
System.out.println(sum3.get());
System.out.println(sum4.getAsInt());
mul2.ifPresent(Util::print);
}
}
콜렉터
- 스트림 파이프라인의 실행 결과를 콜렉션에 수집하고자 하는 경우에 사용
- 매개변수로 java.util 패키지에 정의된 collector 인터페이스 타입을 가진다
- 반환타입은 매개변수인 collector에 의해 결정된다.
- 메소드 종류
- collerct
예시
더보기
package Streamm;
import java.util.IntSummaryStatistics;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Collect1Demo {
public static void main(String[]args) {
Stream<Nation> sn = Nation.nations.stream();
Double avg = sn.collect(Collectors.averagingDouble(Nation::getPopulation));
System.out.println("인구 평균 : " + avg);
sn = Nation.nations.stream();
Long num = sn.collect(Collectors.counting());
System.out.println("나라 개수 : " + num);
sn = Nation.nations.stream();
String name1 = sn.limit(4).map(Nation::getName).collect(Collectors.joining("-"));
System.out.println("4개 나라(방법 1) : " + name1);
sn = Nation.nations.stream();
String name2 = sn.limit(4).collect(Collectors.mapping(Nation::getName, Collectors.joining("+")));
System.out.println("4개 나라(방법 2) : " + name2);
sn = Nation.nations.stream();
Optional<Double> max = sn.map(Nation::getPopulation).collect(Collectors.maxBy(Double::compare));
System.out.println("최대 인구 나라의 인구 수 : " + max);
sn = Nation.nations.stream();
IntSummaryStatistics sta = sn.collect(Collectors.summarizingInt(x -> x.getGdpRank()));
System.out.println(sta);
}
}
콜렉터 : 그룹핑
- groupingBy(Function, Collector) 정적 메소드
- 키-값의 쌍으로 이루어진 Map에 원소를 수집.
- Map의 값은 두 번째 매개값인 Collector가 없다면 List 타입, Collector가 있다면 그에 따라 결정된다.
- 최종 연산 collect()는 groupingBy() 연산에 의하여 수집된 Map타입을 결과로 도출
예시
더보기
import java.util.*;
import java.util.stream.*;
public class GroupingDemo {
public static void main(String[] args) {
Stream<Nation> sn = Nation.nations.stream().limit(4);
Map<Nation.Type, List<Nation>> m1 = sn
.collect(Collectors.groupingBy(Nation::getType));
System.out.println(m1);
sn = Nation.nations.stream().limit(4);
Map<Nation.Type,Long> m2 = sn
.collect(Collectors.groupingBy(Nation::getType,
Collectors.counting()));
System.out.println(m2);
sn = Nation.nations.stream().limit(4);
Map<Nation.Type, String> m3 = sn.collect(
Collectors.groupingBy(Nation::getType,
Collectors.mapping(Nation::getName,
Collectors.joining("#"))));
System.out.println(m3);
}
}
콜렉터 : 파티셔닝
- partitioningBy() 메소드
- 키-값 쌍으로 이루어진 Map에 원소를 수집
- Map의 키는 파티셔닝하기 위해 사용하는 조건이므로 항상 Boolean 타입
- 최종 연산 collect()는 partitioningBy() 연산에 의하여 수집된 Map타입을 결과로 도출
예시
더보기
import java.util.*;
import java.util.stream.*;
public class PartitioningDemo {
public static void main(String[] args) {
Stream<Nation> sn = Nation.nations.stream().limit(4);
Map<Boolean, List<Nation>> m1 = sn
.collect(Collectors.partitioningBy
(p -> p.getType() == Nation.Type.LAND));
System.out.println(m1);
sn = Nation.nations.stream().limit(4);
Map<Boolean,Long> m2 = sn
.collect(Collectors.partitioningBy(
p -> p.getType() == Nation.Type.LAND,
Collectors.counting()));
System.out.println(m2);
sn = Nation.nations.stream().limit(4);
Map<Boolean,String> m3 = sn
.collect(Collectors.partitioningBy(
p -> p.getType() == Nation.Type.LAND,
Collectors.mapping(Nation::getName,
Collectors.joining("#"))));
System.out.println(m3);
}
}