sysUserList 中为何会出现多个具有相同 userId 的 SysUser 对象

背景

PS:本文源于真实开发场景,对应的理论讲解在此教程:Java 8 Stream API 在数据转换中的应用 —— 将列表转换为映射

在日常的开发过程中,我们经常需要将一个包含多个对象的列表转换成一个映射(Map),以便于快速查找和访问数据。在Java 8之前,这样的转换通常需要通过循环等传统方式手动实现,这不仅增加了代码量,还可能引入更多的错误。而Java 8引入的Stream API提供了一种更加简洁、优雅的方式来完成这类任务。

基础概念
  • Stream API:是Java 8新增的一个强大的功能,它可以让你以一种声明式的方式处理数据集合。Stream API可以显著提高Java程序员在处理集合框架时的效率。
  • Map:是一个存储键值对的数据结构,允许通过键快速检索值。
  • Collectors.toMap():是Java 8 Stream API中的一个收集器,用于将流中的元素收集到Map中。
示例代码解析

假设我们有一个sysUserList列表,它包含了多个SysUser对象,每个对象都有一个唯一的userId属性。我们的目标是将这个列表转换成一个Map,其中userId作为键,SysUser对象作为值。

if (CollectionUtil.isNotEmpty(sysUserList)) {
    Map<Long, SysUser> sysUserMap = sysUserList
            .stream()
            .collect(Collectors.toMap(SysUser::getUserId, a -> a, (k1, k2) -> k1));
    
    for (CourseVo dto : courseList) {
        if (sysUserMap.get((long) dto.getCreateUser()) != null) {
            dto.setCreateUserName(sysUserMap.get((long) dto.getCreateUser()).getUserName());
        }
    }
}
代码详解
  1. 条件判断:首先检查sysUserList是否非空,这是为了避免对空列表进行操作导致的潜在错误。

  2. 转换过程:通过调用sysUserList.stream()方法将列表转换为一个流,然后使用collect方法配合Collectors.toMap将流中的元素收集到一个Map中。

    • SysUser::getUserId:指定了Map的键,即SysUser对象的userId属性。
    • a -> a:指定了Map的值,即SysUser对象本身。
    • (k1, k2) -> k1:这是一个合并函数,用于解决键冲突的问题。当流中有多个元素的userId相同时,此函数会决定如何处理这些冲突。在这个例子中,选择保留第一个遇到的对象(k1)并忽略后续相同键的对象(k2)。
  3. 利用Map更新课程信息:遍历courseList,根据每个CourseVo对象的创建者ID(createUser)从sysUserMap中查找对应的SysUser对象,并设置CourseVo对象的createUserName属性。

键冲突处理的深入理解

在实际应用中,键冲突是一个常见的问题。例如,如果sysUserList中存在多个SysUser对象具有相同的userId,那么在构建Map时就需要指定如何处理这种情况。在上面的例子中,我们选择了保留第一次遇到的对象并忽略后续的对象。但是,根据不同的业务需求,我们也可能选择其他策略,比如:

  • 合并对象:可以将所有具有相同键的对象的信息合并到一个新对象中。
  • 选择最新的对象:可以基于某个属性(如创建时间)选择最新的对象。
  • 抛出异常:如果键冲突是不可接受的,可以选择抛出异常。
结论

通过使用Java 8的Stream API,我们可以更高效、更简洁地完成数据转换的任务。Collectors.toMap提供了强大的功能来帮助我们构建映射,同时通过自定义合并函数,我们能够灵活地处理键冲突的情况。这种做法不仅提高了代码的可读性和可维护性,还减少了出错的可能性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邵奈一

教育是一生的事业。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值