티스토리 뷰
● 도입
public static <T, K> Collector<T, ?, Map<K, List<T>>>
groupingBy(Function<? super T, ? extends K> classifier)
- Stream 안의 데이터에 classifier를 적용했을 때 결과값이 같은 값끼리 'List로 모아'서 'Map의 형태로 반환'해주는 collector
- key는 (classifier의 결과값), value는 (그 결과값을 갖는 데이터들의 List)이다.
- 'Map<K, List<T>>'가 최종적으로 반환될 Map의 형태
ex)
- stream에 {1, 2, 5, 7, 9, 12, 13}이 있을 때 classifier가 (x -> x % 3) 이라면
- 반환되는 map은 {0 = [9, 12], 1 = [1, 7, 13], 2 = [2, 5]}
cf) (x -> x % 3) : x를 3으로 나누었을 때 나머지를 return
public static <T, K, A, D> Collector<T, ?, Map<K, D>> groupingBy(
Function<? super T, ? extends K> classifier,
Collector<? super T, A, D> downstream)
- 두 번째 매개변수로 downstream collector를 넘기는 것도 가능, 동일하게 'Map의 형태로 반환'
- 이 경우 List 대신 collector를 적용시킨 값으로 map의 value가 만들어진다. 이때 자주 쓰이는 것이 mapping / reducing 등의 collector
- 'Map<K, D>'가 최종적으로 반환될 Map의 형태
● 실습
1.
package com.fastcampus.functionalprogramming.chapter8;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.fastcampus.functionalprogramming.chapter8.model.Order;
import com.fastcampus.functionalprogramming.chapter8.model.Order.OrderStatus;
public class Chapter8Section7 {
public static void main(String[] args) {
// 같은 일의 자리수끼리 묶어보자 --> 형태 : Map<일의 자리수, 같은 일의 자리수를 가지는 숫자들>
List<Integer> numbers = Arrays.asList(13, 2, 101, 203, 304, 402, 305, 349, 2312, 203);
Map<Integer, List<Integer>> unitDigitMap = numbers.stream()
.collect(Collectors.groupingBy(number -> number % 10));
System.out.println(unitDigitMap);
// ===================================================================================================
// Map<Integer, List<Integer>> 대신 Map<Integer, Set<Integer>>의 형태로 받아보자
List<Integer> numbers2 = Arrays.asList(13, 2, 101, 203, 304, 402, 305, 349, 2312, 203);
Map<Integer, Set<Integer>> unitDigitSet = numbers2.stream()
.collect(Collectors.groupingBy(number -> number % 10, Collectors.toSet()));
System.out.println(unitDigitSet); // 중복값인 203이 하나만 들어있다.
// ===================================================================================================
List<Integer> numbers3 = Arrays.asList(13, 2, 101, 203, 304, 402, 305, 349, 2312, 203);
Map<Integer, List<String>> unitDigitStrMap = numbers3.stream()
.collect(Collectors.groupingBy(number -> number % 10, Collectors.mapping(number -> "unit digit is " + number, Collectors.toList())));
System.out.println(unitDigitStrMap.get(1));
System.out.println(unitDigitStrMap.get(2));
System.out.println(unitDigitStrMap.get(3));
/*
* 순서
* 1. groupingBy method를 통해 List가 만들어진다.
* 2. 그 List에 (number -> "unit digit is " + number)를 적용시킨 후
* 3. Collectors.toList()를 통해 그것들을 담아 List<String> 형태로 반환한다.
*/
}
}
2.
package com.fastcampus.functionalprogramming.chapter8;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.fastcampus.functionalprogramming.chapter8.model.Order;
import com.fastcampus.functionalprogramming.chapter8.model.Order.OrderStatus;
public class Chapter8Section7 {
public static void main(String[] args) {
Order order1 = new Order()
.setId(1001L)
.setAmount(BigDecimal.valueOf(2000))
.setStatus(OrderStatus.CREATED);
Order order2 = new Order()
.setId(1002L)
.setAmount(BigDecimal.valueOf(4000))
.setStatus(OrderStatus.ERROR);
Order order3 = new Order()
.setId(1003L)
.setAmount(BigDecimal.valueOf(3000))
.setStatus(OrderStatus.ERROR);
Order order4 = new Order()
.setId(1004L)
.setAmount(BigDecimal.valueOf(7000))
.setStatus(OrderStatus.PROCESSED);
// TODO OrderStatus 별로 Order 들을 묶어보자 --> Map<OrderStatus, List<Order>>
List<Order> orders = Arrays.asList(order1, order2, order3, order4);
Map<OrderStatus, List<Order>> orderStatusMap = orders.stream().collect(Collectors.groupingBy(Order::getStatus));
System.out.println(orderStatusMap.get(OrderStatus.CREATED));
System.out.println(orderStatusMap.get(OrderStatus.ERROR));
System.out.println(orderStatusMap.get(OrderStatus.PROCESSED));
// ===================================================================================================
// OrderStatus 별로 Order 들을 묶은 후 각 OrderStatus 별 Order들의 amount 합을 구해보자 --> Map<OrderStatus, BigDecimal>
List<Order> orders2 = Arrays.asList(order1, order2, order3, order4);
Map<OrderStatus, BigDecimal> orderStatusToSumOfAmountMap = orders2.stream().collect(
Collectors.groupingBy(Order::getStatus, Collectors.mapping(
Order::getAmount, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)))
);
/*
* 내가 헷갈려서 순서 정리
*
* 1. Collectors.groupingBy(Order::getStatus, ... --> OrderStatus 별로 각 order를 묶어라
* 2. Collectors.mapping --> OrderStatus 별로 묶인 order에 mapping을 할 것이다.
* 3. Order::getAmount --> OrderStatus 별로 묶인 order에서 amount만 가져와라
* 4. Collectors.reducing(BigDecimal.ZERO, BigDecimal::add) --> OrderStatus 별 amount를 모두 더해라(기본값은 '0'으로 설정)
* 5. 그것을 Map<OrderStatus, BigDecimal> 형태로 반환해라
*/
System.out.println(orderStatusToSumOfAmountMap);
}
}
'Backend > Java8' 카테고리의 다른 글
#32 Advanced Stream - forEach (0) | 2022.10.21 |
---|---|
#31 Advanced Stream - Partitioning By (0) | 2022.10.20 |
#29 Advanced Stream - To Map (0) | 2022.10.18 |
#28 Advanced Stream - Collectors (0) | 2022.10.17 |
#27 Advanced Stream - Reduce (0) | 2022.10.16 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Stream
- 빅데이터 분석기사
- Advanced Stream
- spring
- 메모리
- jpa
- Phaser3
- OS
- 알고리즘
- 프로그래머스
- 자료구조
- Phaser
- db
- 코테
- git
- 빅데이터
- DART
- SpringBoot
- node.js
- API
- nosql
- 코딩테스트
- SQL
- java
- Java8
- 프로세스
- MySQL
- MongoDB
- 운영체제
- Spring Boot
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함