1. 分组 groupingBy()
- Function 是分类函数,可以把流中的元素分成不同的组
- 分组操作的结果是一个Map,把分组函数返回的值作为映射的键,把流中所有具有这个分类值的项目的列表作为对应的映射值
- 键:分类值,值:包含分类值的列表
1.2 分组操作
- Collector.groupingBy(Function classifier)
@Test
public void group() {
List<OrderDTO> orderDTOS = Arrays.asList(new OrderDTO("1001", "20230101", 0, 30L),
new OrderDTO("1002", "20230102", -1, 100L),
new OrderDTO("1003", "20230103", 0, 50L));
// 按 orderStatus 分组
Map<Integer, List<OrderDTO>> orderStatusMap = orderDTOS.stream().collect(
Collectors.groupingBy(OrderDTO::getOrderStatus));
Map<Boolean, List<OrderDTO>> booleanMap = orderDTOS.stream().collect(
groupingBy(orderDO -> orderDO.getOrderAmount() > 50));
}
@Data
public class OrderDTO implements Serializable {
private static final long serialVersionUID = 177087236253361067L;
private String orderCode;
private String tradeId;
private Integer orderStatus;
private Long orderAmount;
public OrderDTO(String orderCode, String tradeId, Integer orderStatus, Long orderAmount) {
this.orderCode = orderCode;
this.tradeId = tradeId;
this.orderStatus = orderStatus;
this.orderAmount = orderAmount;
}
}
1.3 多级分组
- 把内层 groupingBy 传递给外层 groupingBy
- n 级分组就会得到一个代表 n 级树形结构的 n 级 Map
@Test
public void multilevel() {
List<OrderDTO> orderDTOS = Arrays.asList(new OrderDTO("1001", "20230101", 0, 30L),
new OrderDTO("1002", "20230102", -1, 100L),
new OrderDTO("1003", "20230103", 0, 50L));
Map<Integer, Map<String, List<OrderDTO>>> map = orderDTOS.stream().collect(
groupingBy(OrderDTO::getOrderStatus, // 一级分类函数
groupingBy(OrderDTO::getOrderCode))); // 二级分类函数
}
1.4 分组收集
@Test
public void collect() {
List<OrderDTO> orderDTOS = Arrays.asList(new OrderDTO("1001", "20230101", 0, 30L),
new OrderDTO("1002", "20230101", 0, 100L),
new OrderDTO("1003", "20230103", -1, 50L));
Map<String, Long> collect = orderDTOS.stream().collect(
groupingBy(OrderDTO::getTradeId, summingLong(OrderDTO::getOrderAmount)));
System.out.println(collect);
}
打印结果:
{20230101=130, 20230103=50}
1.5 操作分组元素
Java 9 新增两个收集器:Collectors.filtering 和 Collectors.flatMapping
过滤操作 Collectors.filtering(Predicate predicate, Collector downstream)
映射操作 Collectors.mapping(Function mapper, Collector downstream)
Map<String, List<OrderDTO>> collect1 = orderDTOS.stream().collect(groupingBy(OrderDTO::getType, filtering(orderDO -> orderDO.getId() > 20, toList())));
Map<String, List<Integer>> collect2 = orderDTOS.stream().collect(groupingBy(OrderDTO::getType, mapping(OrderDO::getId, toList())));
Map<String, Set<String>> collect = goodsList.stream().collect(
groupingBy(Goods::getName,
flatMapping(goods -> maps.get(goods.getName()).stream(), Collectors.toSet())));
2. 分区 Collectors.partitioningBy()
- 分区是分组的特殊情况:由一个谓词(返回一个布尔值的函数)作为分类函数,它称分区函数
- 分区函数返回一个布尔值,最多可以分为两组:true是一组,false是一组
- Map 的键类型是 Boolean
@Test
public void partition() {
List<OrderDTO> orderDTOS = Arrays.asList(new OrderDTO("1001", 30L),
new OrderDTO("1002", 50L), new OrderDTO("1003", 100L));
Map<Boolean, List<OrderDTO>> map = orderDTOS.stream()
.collect(partitioningBy(orderDO -> orderDO.getOrderAmount() > 50));
System.out.println(JSON.toJSONString(map));
// 获取值
List<OrderDTO> result = map.get(true);
}
输出 map 值:
{
false: [
{
"orderAmount": 30,
"tradeId": "1001"
},
{
"orderAmount": 50,
"tradeId": "1002"
}
],
true: [
{
"orderAmount": 100,
"tradeId": "1003"
}
]
}
网友评论