在现代 Java 开发中,Stream API(流式处理 API)、Collectors.toMap、方法引用(Method Reference) 和 Lambda 表达式 是 Java 8 引入的强大特性,极大提升了代码的简洁性和表达力。本文将围绕以下代码片段,深入探讨这四个主题,带你领略函数式编程的魅力!
Map<String, PaymentRecord> finalResultsMap = paymentRecordRepository
.findAllByConsignmentSettlementIdAndAdminId(consignmentSettlementId, adminId)
.stream()
.collect(Collectors.toMap(PaymentRecord::getOrderNo, pr -> pr, (pr1, pr2) -> pr1));
我们将通过表格总结、Mermaid 流程图、时序图和思维导图,结合实际案例,全面解析这些技术的原理和应用!
主题 | 英文全称 | 中文全称 | 描述 | 代码中的体现 |
---|---|---|---|---|
Stream API | Stream Application Programming Interface | 流式处理应用程序接口 | 提供声明式处理集合的方式,支持链式操作 | .stream() 将 List 转为流 |
Collectors.toMap | Collectors to Map | 收集器转映射 | 将流元素收集为 Map ,指定键、值和合并逻辑 |
.collect(Collectors.toMap(...)) 生成 Map ️ |
方法引用 | Method Reference | 方法引用 | 简化 Lambda 表达式的语法糖 | PaymentRecord::getOrderNo 提取 orderNo 作为键 |
Lambda 表达式 | Lambda Expression | Lambda 表达式 | 定义匿名函数,支持函数式编程 | pr -> pr 和 (pr1, pr2) -> pr1 定义值和合并逻辑 ️ |
.stream()
将 paymentRecordRepository.findAllByConsignmentSettlementIdAndAdminId
返回的 List
转换为 Stream
,为后续的 collect
操作铺平道路。List<PaymentRecord> records = paymentRecordRepository.findAllByConsignmentSettlementIdAndAdminId(1, 100);
Stream<PaymentRecord> stream = records.stream(); // 转换为流
Collectors.toMap
是 Stream API 中的收集器方法,用于将流元素收集为 Map
。它需要三个参数:
Map
的键。Map
的值。.collect(Collectors.toMap(PaymentRecord::getOrderNo, pr -> pr, (pr1, pr2) -> pr1))
PaymentRecord::getOrderNo
,提取 orderNo
(字符串)作为键。pr -> pr
,直接使用 PaymentRecord
对象作为值。(pr1, pr2) -> pr1
,若 orderNo
重复,保留第一个记录。PaymentRecord
列表转换为以 orderNo
为键的 Map
,便于快速查找。PaymentRecord(orderNo="CON20250521-001", id=1)
PaymentRecord(orderNo="CON20250521-002", id=2)
{
"CON20250521-001": PaymentRecord(id=1),
"CON20250521-002": PaymentRecord(id=2)
}
PaymentRecord::getOrderNo
是实例方法引用,等价于 pr -> pr.getOrderNo()
,提取每个 PaymentRecord
的 orderNo
字段。Class::staticMethod
Class::instanceMethod
(本例中使用)object::instanceMethod
Class::new
getOrderNo
返回非 null
,否则可能抛出 NPE(Null Pointer Exception,空指针异常)。pr -> pr
:值映射函数,返回 PaymentRecord
本身。(pr1, pr2) -> pr1
:合并函数,处理 orderNo
重复,保留第一个记录。Function
和 BinaryOperator
)。Function<PaymentRecord, String> keyMapper = pr -> pr.getOrderNo(); // 等价于 PaymentRecord::getOrderNo
Function<PaymentRecord, PaymentRecord> valueMapper = pr -> pr; // 值映射
BinaryOperator<PaymentRecord> mergeFunction = (pr1, pr2) -> pr1; // 合并函数
以下是代码执行的 Mermaid 流程图,所有文本用双引号包裹:
说明:
PaymentRecord
列表。stream()
进入函数式处理。toMap
将流转换为 Map
,指定键、值和合并逻辑。以下是时序图,展示代码的交互过程,文本不加双引号:
说明:
以下是 Markdown 格式的思维导图,总结核心内容:
空值处理:
PaymentRecord.getOrderNo()
返回 null
,toMap
可能抛出 NPE(Null Pointer Exception,空指针异常)。可通过过滤解决:.filter(pr -> pr.getOrderNo() != null)
.collect(Collectors.toMap(PaymentRecord::getOrderNo, pr -> pr, (pr1, pr2) -> pr1));
键冲突:
(pr1, pr2) -> pr1
假设 orderNo
唯一。若业务允许重复键,需调整合并逻辑(如合并记录字段)。️性能:
toMap
生成的默认 HashMap
查找效率为 O(1)。⚡扩展性:
filter
、map
)增强功能:.stream()
.filter(pr -> pr.getTotalAmount() != null)
.collect(Collectors.toMap(PaymentRecord::getOrderNo, pr -> pr, (pr1, pr2) -> pr1));
通过分析代码 Map
,我们深入探讨了 Stream API、Collectors.toMap、方法引用 和 Lambda 表达式 的原理与应用。这些 Java 8 特性使代码更简洁、优雅,同时提高了可读性和维护性。希望本文的表格、流程图、时序图和思维导图能帮助你全面掌握这些技术!
有任何疑问,欢迎留言讨论!