Java中Stream使用示例-对实体List分组且保留原数据顺序并对分组后的每组内的数据进行部分业务逻辑修改操作

场景

Java8新特性-Stream对集合进行操作的常用API:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/126070657

针对Stream的一个常用的业务场景:

对实体List分组且保留原数据顺序并对分组后的每组内的数据进行部分业务逻辑修改操作

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi

实现

先看代码实现:

复制代码
        Map<String, List<WarehouseTankInfoDTO>> dataMap = dataList.stream()
                .collect(Collectors.groupingBy(
                        WarehouseTankInfoDTO::getRelateCompanyName,
                        LinkedHashMap::new, // 保持插入顺序
                        Collectors.collectingAndThen(
                                Collectors.toList(),
                                list -> {
                                    // 对每组List<WarehouseTankInfoDTO>进行逻辑处理
                                    return list.stream()
                                            .peek(dto -> {
                                                // 示例:修改DTO的某个字段
                                                if (null != dto.getStoreName()&& null!=dto.getRelateCompanyName()&& !dto.getStoreName().equals(dto.getRelateCompanyName()) ) {
                                                    dto.setStoreName(dto.getRelateCompanyName());
                                                }
                                            })
                                            .collect(Collectors.toList());
                                }
                        )
                ));

代码详细讲解:

  1. 基础结构

    Map<String, List<WarehouseTankInfoDTO>> dataMap = dataList.stream()
    .collect(Collectors.groupingBy(...));

核心逻辑:按公司名称分组并保持原始顺序

2、分组逻辑实现

复制代码
groupingBy(
    WarehouseTankInfoDTO::getRelateCompanyName, // 分组Key提取器
    LinkedHashMap::new, // Map实现类选择
    Collectors.collectingAndThen(...)  // 下游收集器
)

LinkedHashMap::new

保证分组后的Map键顺序与数据原始出现顺序一致(普通HashMap不保证顺序)

典型应用场景:需要按特定顺序展示分组结果的报表生成

3、分组后处理

复制代码
Collectors.collectingAndThen(
    Collectors.toList(),
    list -> {
        return list.stream()
            .peek(dto -> {
                // 字段修正逻辑
                if (null != dto.getStoreName()  &&
                    null != dto.getRelateCompanyName()  &&
                    !dto.getStoreName().equals(dto.getRelateCompanyName()))  {
                    dto.setStoreName(dto.getRelateCompanyName());
                }
            })
            .collect(Collectors.toList());
    }
)

双阶段处理:

先执行常规toList()收集

然后对每个分组List进行流式处理

字段修正逻辑:

当storeName与relateCompanyName不同且非空时

用relateCompanyName覆盖storeName

业务意图:统一相同公司下的仓库名称标准

4、注意这里的peek的用法

方法定义

Stream<T> peek(Consumer<? super T> action)

类型:中间操作(Intermediate Operation)

参数:接收一个Consumer函数式接口

返回值:返回新的Stream(支持链式调用)

典型用途

调试观察:查看流处理中间状态

副作用操作:修改元素内部状态(如示例中的DTO字段修改)

日志记录:在流水线中插入日志点

选择peek()而非map()的原因是:

无返回值需求:只需要修改对象状态,不需要转换对象类型

保持流结构:不改变流中元素引用,仅修改元素内部状态

操作简洁性:比map+对象拷贝更简洁(当只需部分字段修改时)

相关推荐
大模型玩家七七8 小时前
基于语义切分 vs 基于结构切分的实际差异
java·开发语言·数据库·安全·batch
寻星探路13 小时前
【深度长文】万字攻克网络原理:从 HTTP 报文解构到 HTTPS 终极加密逻辑
java·开发语言·网络·python·http·ai·https
曹牧16 小时前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
爬山算法17 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
kfyty72517 小时前
集成 spring-ai 2.x 实践中遇到的一些问题及解决方案
java·人工智能·spring-ai
猫头虎17 小时前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven
李少兄17 小时前
在 IntelliJ IDEA 中修改 Git 远程仓库地址
java·git·intellij-idea
忆~遂愿17 小时前
ops-cv 算子库深度解析:面向视觉任务的硬件优化与数据布局(NCHW/NHWC)策略
java·大数据·linux·人工智能
小韩学长yyds17 小时前
Java序列化避坑指南:明确这4种场景,再也不盲目实现Serializable
java·序列化