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+对象拷贝更简洁(当只需部分字段修改时)

相关推荐
luck_bor12 分钟前
集合进阶(Collections Set List)
java
敲敲千反田15 分钟前
Spring AI
java·人工智能·spring
拽着尾巴的鱼儿27 分钟前
spring 动态代理
java·后端·spring
gf132111132 分钟前
python_【更新已发送的消息卡片】
java·前端·python
WL_Aurora37 分钟前
Java字符输入全攻略
java·开发语言
Hello.Reader1 小时前
算法基础(十三)——随机算法为什么有时主动引入随机性
java·数据库·算法
likerhood1 小时前
ConcurrentHashMap底层数据结构和面试常见问题
java·数据结构·面试·hashmap
云烟成雨TD1 小时前
Spring AI Alibaba 1.x 系列【52】Interrupts 中断机制:案例演示
java·人工智能·spring
老鱼说AI1 小时前
现代 LangChain 开发指南:从 LCEL 原理到企业级 RAG 与 Agent 实战
java·开发语言·人工智能·深度学习·神经网络·算法·机器学习
云烟成雨TD2 小时前
Spring AI Alibaba 1.x 系列【51】Graph 整体运行全流程
java·人工智能·spring