출처 - Java의 정석 기초편 (남궁 성)
1. 스트림 최종연산
- 핵심: reduce(), collect()
void forEach(Consumer<? super T> action)
void forEachOrdered(Consume<? super T> action) // 병렬 스트림 순서 유지
long count() // 스트림 요소 개수
Optional<T> max(Comparator<? super T> comparator)
Optional<T> min(Comparator<? super T> comparator)
Optional<T> findFirst() // 직렬 첫 번째 요소
Optional<T> findAny() // 병렬 아무거나 하나
boolean allMatch(Predicate<T> p) // 모두 만족
boolean anyMach(Predicate<T> p) // 하나라도 만족
boolean nomeMach(Predicate<T> p) // 모두 만족하지 않는지
Object[] toArray()
A[] toArray(IntFunction<A[]> generator)
Optional<T> reduce(BinaryOperator<T> accumulator) // 요소 하나씩 줄여가며 계산
R collect(Collector<T,A,R> collector) // 그룹 작업
2. forEach()
- 스트림 모든 요소에 지정된 작업 수행
- forEachOrdered(): 병렬시 순서 유지
IntStream.range(1, 10).parellel().forEach(System.out::print); // 524931678
IntStream.range(1, 10).parellel().forEachOrderedd(System.out::print); // 123456789
3. 조건검사
- 조건검사(매개변수 Predicate), 반환타입 boolean): allMatch(), anyMatch(), noneMatch()
- 조건 일치하는 요소 찾기: findFirst(), findAny()
boolean noFailed = stuStream.anyMatch(s->s.getTotalScore()<=100)
Optional<Student> result = stuStream.filter(s->s.getTotalScore()<=100).findFirst(); // 직렬
Optional<Student> result = parallelStream.filter(s->s.getTotalScore()<=100).findAny(); // 병렬
4. reduce()
- 초기값(identity)과 연산(Binary Operator)으로 스트림 요소를 하나씩 줄여가며 누적연산(accumulate) 수행
- 매개변수 타입: BinaryOperator<T>
- 반환타입: 초기값 있으면 identity 반환, 없으면 Optional<T> 반환
- 활용: count(). max(), min(). collect()
Optional<T> reduce(BinaryOperator<T> accumulator)
T reduce(T identity, BinaryOperator<T> accumulator)
int count = intStream.reduce(0, (a,b) -> a + 1); // count()
int sum = intStream.reduce(0, (a,b) -> a + b); // sum()
int max = intStream.reduce(Integer.MIN_VALUE, (a,b) -> a>b ? a:b) // max()
int min = intStream.reduce(Integer.MAX_VALUE, (a,b) -> a>b ? a:b) // min()
5. collect(), Collector, Collectors
- collect(): Collector를 매개변수로 하는 스트림의 최종 연산
- Collector: 수집(collect)에 필요한 메서드를 정의해둔 인터페이스
- Collectors: 다양한 기능의 Collector를 구현체 제공하는 클래스
Object collect(Collector collector)
6. Collectors 클래스
- 변환: mapping(), toList(), toSet(), toMap(), toCollection()
- 통계: countiong(), summingInt(), averagingInt(), maxBy(), minBy(), summarizingInt()
- 문자열 결합: joining()
- 리듀싱: reducing()
- 그룹화와 분할: groupingBy(), partitioningBy(), collectingAndThen()
7. 스트림→컬렉션, 배열
- 스트림→컬렉션: collect()메서드→toList(). toSet(), toMap(), toCollection()
- 스트림→배열: toArray()메서드
List<String> names = stuStream.map(Student::getName).collect(Collectors.toList());
ArrayList<String> list = names.stream().collect(Collectors.toCollection(ArrayList::new));
Map<String,Person> map = personStream.collect(Collectors.toMap(p->p.getRegId(), p->p));
Student[] stuNames = studentStream.toArray(Student[]::bew); // ok
Object[] stuNames = studentStream.toArray(); // 매개변수 없는 것 Object[] 반환
8. 스트림 통계
- 전체: count(), sum(), max(), min()
- 그룹별: counting(), summingInt(), maxBy(), minBy()
import static java.util.stream.collectors.*;
long count = stuStream.count(); // 전체 카운트
long count = stustream.collect(counting()); // 그룹별 카운트 Collectors.counting()
long totalScore = stuStream.mapToInt(Student::getTotalScore).sum();
long totalScore = stuStream.collect(summingInt(Student::getTotalScore));
Optional<Student> topStudent = stuStream.max(Comparator.comparingInt(Student::getTotalScore));
Optional<Student> topStudent = stuStream.collect(maxBy(Comparator.comparingInt(Student::getTotalScore)));
9. 스트림 리듀싱
- 전체: reduce()
- 그룹별: reducing()
IntStream intStream = new Random().ints(1,46).distinct().limit(6);
OptionalInt max = intStream.reduce(Integer::max); // 전체 리듀싱
Optional<Integer> max = intStream.boxed().collect(reducing(Integer::max)); // 그룹별 리듀싱
long sum = intStream.reduce(0, (a,b) -> a + b);
long sum = intStream.boxed().collect(reducing(0, (a,b) -> a + b));
int grandTotal = stuStream.map(Student::getTotalScore).reduce(0, Integer::sum);
int grandTotal = stuStream.collect(reducing(0, Student::getTotalScore, Integer::sum)); // map() + reduce()
10. 스트림→문자열로 결합
- joining()
- 구분자, 접두사, 접미사 지정 가능
String studentNames = stuStream.map(Student::getName).collect(joining()); // Collectors.joining()
String studentNames = stuStream.map(Student::getName).collect(joining(",")); // 구분자
String studentNames = stuStream.map(Student::getName).collect(joining(",","[","]"));
11. 스트림 분할
- Collectors.partitioningBy()
- 스트림 2분할
- 다중 분할
Map<Boolean, List<Student>> stuBySex = stuStream.collect(partitioningBy(Student::isMale)); // 성별로 2분할
List<Student> maleStudent = stuBySex.get(true); // Map에서 남학생 목록 얻음
List<Student> femaleStudent = stuBySex.get(false); // Map에서 여학생 목록 얻음
Map<Boolean, Long> stuNumBySex = stuStream.collect(partitioningBy(Student::isMale, counting()));
System.out.println("남학생 수 :" + stuMumBySex.get(true));
System.out.println("여학생 수 :" + stuNumBySex.get(false));
Map<Boolean, Map<Boolean, List<Student>>> failedStuBySex = stuStream
.collect(
partitioningBy(Student::isMale, // 성별 분할
partitioningBy(s -> s.getScore() < 150) // 성적 분할
)
);
List<Student> failedMaleStu = failedStuBySex.get(true).get(true); // 남자 불합격
List<Student> failedMaleStu = failedStuBySex.get(false).get(true); // 여자 불합격
12. 스트림 그룹화
- Collectors.groupingBy()
- 스트림 n분할
- 다중 그룹화
Map<Integer, List<Student>> stuByBan = stustream
.collect(groupingBy(Student::getBan, toList())); // toList() 생략가능
Map<Integer, HashSet<Student>> stuByHak = stuStream
.collect(groupingBy(Student::getHak, toCollection(HashSet::new)));
Map<Integer, Map<Integer, List<Student>>> stuByHakAndBan = stuStream
.collect(groupingBy(Student::getHak, // 학년별 그룹화
groupingBy(Student::getBan) // 반별 그룹화
));
'Java' 카테고리의 다른 글
Optional<T>객체 (0) | 2022.12.14 |
---|---|
스트림 중간연산 (0) | 2022.12.14 |
스트림(Stream) (0) | 2022.12.09 |
람다, 함수형 인터페이스, 메서드 참조 (0) | 2022.12.08 |
쓰레드 메서드 (0) | 2022.11.19 |