使用Collectors.partitioningBy可按成功/失败快速分组统计,返回Map<Boolean, List<Payment>>,true组为成功记录,false组为失败记录,并支持嵌套下游收集器实现计数、映射或二次分组。

在支付系统中,常需将一批支付结果按“成功”或“失败”快速分组统计。使用 Collectors.partitioningBy 是最简洁、语义最清晰的方式之一——它基于布尔条件将流分为两个 List(true 组和 false 组),天然契合“成功/失败”这类二元状态分类。
核心用法:用 Predicate 定义成功逻辑
关键在于提供一个返回 boolean 的谓词(Predicate),例如判断支付对象的 status 是否为 "SUCCESS" 或 isSuccess() 是否为 true:
- 若支付实体有
isSuccess()方法,直接传入方法引用:Collectors.partitioningBy(Payment::isSuccess) - 若状态是字符串字段(如
status),可写 Lambda:Collectors.partitioningBy(p -> "SUCCESS".equals(p.getStatus())) - 注意 null 安全:建议提前过滤 null 或在谓词中判空,例如
p != null && "SUCCESS".equals(p.getStatus())
获取分组结果:Map> 结构
执行后得到一个 Map<boolean list>></boolean>,其中:
-
map.get(true)→ 所有成功的支付记录(可能为 null,建议用map.getOrDefault(true, Collections.emptyList())) -
map.get(false)→ 所有失败的支付记录 - 不推荐直接用
get(null);partitioningBy 不处理 null 输入,null 元素会被归入 false 组(取决于谓词逻辑)
进阶组合:嵌套下游收集器做统计或转换
可在 partitioningBy 中指定下游收集器,避免额外遍历。例如:
- 统计数量:
Collectors.partitioningBy(Payment::isSuccess, Collectors.counting())→ 返回Map<boolean long></boolean> - 提取订单号列表:
Collectors.partitioningBy(Payment::isSuccess, Collectors.mapping(Payment::getOrderId, Collectors.toList())) - 按失败原因分组(仅对失败集合):
Collectors.partitioningBy(Payment::isSuccess, Collectors.groupingBy(Payment::getFailureCode))
实际应用示例(简化版)
假设你有一批 Payment 对象,想分离成功/失败并分别记录日志:
Map<Boolean, List<Payment>> result = payments.stream()
.filter(Objects::nonNull)
.collect(Collectors.partitioningBy(Payment::isSuccess));
List<Payment> successes = result.getOrDefault(true, Collections.emptyList());
List<Payment> failures = result.getOrDefault(false, Collections.emptyList());
log.info("成功 {} 笔,失败 {} 笔", successes.size(), failures.size());
failures.forEach(f -> log.warn("失败订单:{},原因:{}", f.getOrderId(), f.getFailureReason()));

















