java8lambda表达式对集合分组并且排序(记一次性能优化案例)

JDK8的Lambda表达式怎样简化集合操作? Lambda表达式通过​​、​​函数式接口​​和​​接口默认方法​​三位一体,将Java集合操作从如何做(How)的指令描述,转向做什么(What)的意图声明。这种转变不仅减少了代码量,更通过并行流、惰性求值等特性提升了运行时效率。随着后续版本如Java 17的Record类和的加入,函数式集合操作将继续深化,成为高可维护性Java代码的基石。​​最佳实践提示​​:简单遍历优先选forEach而非完整Stream链避免在Lambda中修改外部状态(违反无副作用原则)并行流谨慎用于I/O阻塞任务。 阅读详情

最近遇到个需求是这样的:

写一个类似于通讯录的简单功能,要求是首先按照部门显示列表,然后点击部门下拉显示部门里面的人员信息,且人员信息按照职位排序。

先分析数据结构:

最外层是部门,部门里面是员工,且项目是统一返回数据格式。

{
    "code": 0,
    "data": [
        {
            "name": "部门名称",
            "userData": [
                {
                    "deptName": "部门名称",
                    "info": "部门名称+职位",
                    "phone": "电话号码",
                    "userName": "员工姓名"
                }
            ]
        },
        {
            "name": "部门名称",
            "userData": [
                {
                    "deptName": "部门名称",
                    "info": "部门名称+职位",
                    "phone": "电话号码",
                    "userName": "员工姓名"
                }
            ]
        }
    ],
    "message": "success"
}

数据格式大概就是这样。然后分析写法。正常来说需要用sql将这些数据一次性分组并返回出来,本人没有找到合适的方法。然后打算用最原始的方法,就是先查出所有的部门,再遍历部门查询出部门里面所有的人员,再将数据返回。下面贴上代码。

List<PageData> deptAll = (List<PageData>) dao.findForList("AddressListMapper.querydeptAll", pageData);
        //创建list保存所有部门和部门人员
        List<PageData> deptPersonnelAll = new ArrayList<PageData>();
        //遍历获取到的部门查询相对应得人员信息
/*        for (HashMap<String, Object> dept : deptAll) {
            //获取部门名称
            String deptName = String.valueOf(dept.get("name"));
            //获取部门code
            String deptCode = String.valueOf(dept.get("code"));
            //根据部门code查询部门对应的人员
            PageData pageDatap = new PageData();
            pageDatap.put("deptid", deptCode);
            ArrayList<PageData> personnelList = queryPersonnel(pageDatap);
            //将数据存封装为map并存进list
            PageData deptSingle = new PageData();
            deptSingle.put("name", deptName);
            deptSingle.put("userData", personnelList);
            deptPersonnelAll.add(deptSingle);
        }*/
        deptAll.stream().forEach(dept -> {
            //获取部门名称
            String deptName = String.valueOf(dept.get("name"));
            //获取部门code
            String deptCode = String.valueOf(dept.get("code"));
            //根据部门code查询部门对应的人员
            PageData pageDatap = new PageData();
            pageDatap.put("deptid", deptCode);
            ArrayList<PageData> personnelList = null;
            try {
                personnelList = queryPersonnel(pageDatap);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //将数据存封装为map并存进list
            PageData deptSingle = new PageData();
            deptSingle.put("name", deptName);
            deptSingle.put("userData", personnelList);
            deptPersonnelAll.add(deptSingle);
        });
        return deptPersonnelAll;

上面遍历集合写了两种方式,一种是以前的for循环写法,另一种是用表达式。

但是这种方式会出现一个性能问题,比如说有10000个部门,就需要查询10000次数据库。这样会增大数据库的压力和查询时间。所以这样就需要优化。

优化:

优化的方式就是在数据一次查出所有的人员信息,并将人员信息和部门信息进行关联,这样就能知道每个人所对应的部门。然后用java代码可以对数据进行分组。

贴代码:

public List<Map<String, Object>> getAllPersonnel(PageData pageData) throws Exception {
    //查询类型对应的人员
    List<AddressList> addressList = (List<AddressList>) dao.findForList("AddressListMapper.getAllPersonnel", pageData);
    //lambda表达式对数据进行分组
    Map<String, List<AddressList>> collect = addressList.stream().collect(Collectors.groupingBy(AddressList::getDeptName));
    //处理分组后的数据
    //创建一个list集合存储所有数据
    List<Map<String, Object>> maps = new ArrayList<>();
    //遍历分组后的数据,进行组装
    collect.forEach((k, v) -> {
        HashMap<String, Object> map = new HashMap<>();
        map.put("name", k);
        map.put("userData", v);
        maps.add(map);
    });
    return maps;
}

这边分组是用的表达式分组的,定义一个对象,将数据库查出来的数据封装进去,然后按照属性进行分组。这样就可以避免多次请求数据库。

处理排序:

这样优化完后还有一个排序的问题。

解决办法:

上面代码中groupingBy有三个参数

第一个参数:分组按照什么分类

第二个参数:分组最后用什么容器保存返回值(默认是HashMap::new)

第三个参数:按照第一个参数分类后,对应的分类的结果如何收集。(Collectors.toList)

这边主要问题是数据库里面将数据排序好之后返回到代码里面。代码里面对数据进行分组之后,数据的顺序发生了改变。

map里面的有序集合LinkedHashMap。这里可以使用这个集合作为分组后用来保存返回值的容器。这样就解决了分组后的排序问题。

 

XCKU060光纤卡学习资料保存:基于kintex UltraScale XCKU060的双路QSFP+光纤PCIe 卡 基于kintex UltraScale XCKU060的双路QSFP+光纤PCIe 卡 一、板卡概述 本板卡系我司自主研发,基于XilinxUltraScaleKintex系列FPGAXCKU060-FFVA1156-2-I架构,支持PCIEGen3x8模式的高速信号处理板卡,搭配两路40GQSFP+接口,两组64-bitDDR4,每组容量8Gbyte,可稳定运行在2400MT/s。板卡具有自控上电顺序,BP... 阅读详情

相关推荐

别再混淆了!一文彻底搞懂STM32的BootROM、BootLoader和启动模式(附启动流程图)

本文深入解析STM32的启动机制,详细讲解BootROM、BootLoader与启动模式的区别与联系,并提供实战指南。通过清晰的启动流程图和配置示例,帮助开发者彻底理解STM32启动流程,解决常见的启动问题,提升嵌入式开发效率。

weixin_33728268的博客 538

Java小知识:使用Lambda表达式,对List集合分组并排序

使用Lambda表达式,对List集合分组并排序

危险、的博客 9127

电路仿真软件PSIM简介

PSIM的基本使用操作...

qq_55203246的博客 7179

Lambda常用功能(排序、分组、去重、累加、截断、移除)

合并标志值,它将参与累加函数和合并函数的运算(即提供一个默认值,在流为空的时候返回该值,当流不为空时,该值作为起始值,参与每次累加或合并计算)// 根据比较器进行排序(升序),可以通过实现Comparator.comparing()方法,来创建自定义的比较器。:合并函数(合并多个标志,与collect方法的combiner参数原理类似,都是用于多线程的合并策略):同一分组的合并方法,将同一个类型合并为指定类型,该方法返回的是键值对的值。:提供一个方法,该方法的返回值是键值对的健。

qq_36138652的博客 3900

大整数因数分解工具——yafu

可以将大整数放在一个新建文件中——data.txt,最后面一定要换行,不然会出现eof;done processing batchfile,运行命令。2.点击设置——系统——系统信息——高级系统设置——环境变量——点击PATH(上下都可以)——新建 添加yafu-x64.exe 所在路径——点击确定。,如果整数数过长,会出现错误mismatched parens;1.找到yafu-x64.exe 所在的文件路径。如果出现以下图像,说明配置成功。3.打开cmd,输入。

l2ohvef的博客 6156

ITIL 4 Foundation 自学通关笔记1

ITIL 4 Foundation 自学通关笔记

m0_58817196的博客 953

非常全面的lambda表达式对List集合去重、分组、排序、过滤、求和、最值方法工具类

我们经常会对list集合去重,于是我自己花了点时间将如何用 lambda表达式对list集合去重做了封装和测试,方便以后快速使用。包括对对象集合中的某个属性去重等。如果有特殊的list去重要求,可以自行对下列方法进行修改。 下列方法是本人验证过比较简便的写法,请参考: import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.f

严老板的技术梦想博客 4万+

uniapp - 热更新提示:WGT安装包中manifest.json文件不存在 | unexpected EOF!报错详细解决,完美搞定WGT安装包中WWW目录下manifest.json不存在问题

uniapp,安卓android,苹果ios,热更新,热更新code:-1202报错,,WGT热更新报错,uniapp热更新wgt出现报错manifest.json文件不存,uniapp安卓苹果软件热更新时出现错误unexpected EOF!如何解决,怎么解决热更新wgt报错,app新版本下载安装报错WGT安装包中manifest.json文件不存在,WGT安装包中WWW目录下manifest.json不存在,uniapp热更新报错安装失败[-1201]:WGT/WGTU文件格式错误,uniapp-wgt

✅ 精选推荐文章 1万+

Java8中lambda表达式分组后去重、排序、合并

List<HomeSettings> list = settingsList.stream().filter(x -> x.getCode().contains(oneOuid)) .collect( Collectors.groupingBy(HomeSettings::getName, Collectors.mapping(

qq_2908411009的博客 2442

【OpenCV实战】简洁易懂的车牌号识别Python+OpenCV实现“超详解”(含代码)

简洁易懂的车牌号识别Python实现(含代码)1、整体思路2、代码详解 1、整体思路 2、代码详解

qq_40784418的博客 9万+

【云原生技术】SonarQube 生态中PMD插件和P3C插件详细介绍

4. 在项目中如何选择 / 组合 1. 小团队、对《阿里规约》认同度高 → 直接启用 **P3C**,配合 SonarJava 基本够用。 2. 追求全面 Bug/安全检测 + 额外编码规范 → **SonarJava + PMD**(必要时加 P3C 少量规则)。 3. 大型多团队,希望“一本规约”统一风格 → **P3C 为主**,再补充 SonarJava/PMD 的 Bug 与安全规则。 4. 通过 Quality Gate 控制:将 **Blocker/Critical** Bug

weixin_46453070的博客 1366

java 8 lambda表达式list操作分组、过滤、求和、最值、排序、去重

java8的lambda表达式提供了一些方便list操作的方法,主要涵盖分组、过滤、求和、最值、排序、去重。跟之前的传统写法对比,能少写不少代码。 新建实体类 package com.vvvtimes.vo; import java.math.BigDecimal; import java.util.Date; public class User { private Long ...

gsls200808的专栏 11万+

Vue3 - Element Plus上传组件el-upload上传多个文件时,让on-change监听事件仅执行一次并获取最终文件列表方法(开启多选文件并手动上传,拿到文件列表统一循环调用接口上传)

vue3,elementplus,Upload上传,el-upload,文件上传组件,上传组件on-change里执行多次,取消自动上传后change重复执行问题,upload上传多个文件后导致on-change执行多次拿不到最终文件列表,Element-plus的upload组件on-change不断执行怎么办,上传多个文件多次执行调用,上传多个文件时如何只执行一次on-change方法拿到最终的文件列表,vue3elementplus上传组件开启多个上传后导致change方法执行好几次,仅调用一

🏆 前端领域优质创作者 1万+

lamda list 分组_java8lambda表达式对集合分组并且排序(记一次性能优化案例)

最近遇到个需求是这样的:写一个类似于通讯录的简单功能,要求是首先按照部门显示列表,然后点击部门下拉显示部门里面的人员信息,且人员信息按照职位排序。先分析数据结构:最外层是部门,部门里面是员工,且项目是统一返回数据格式。{"code": 0,"data": [{"name": "部门名称","userData": [{"deptName": "部门名称","info": "部门名称+职位","pho...

weixin_39978350的博客 1396

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Java8新特性Lambda表达式&Stream流&方法引用最全集锦

文章目录流支持流创建随机数流int 类型的范围generate()iterate()流的建造者模式Arrays正则表达式中间操作跟踪和调试流元素排序移除元素应用函数到元素在 `map()` 中组合流Optional类便利函数创建 OptionalOptional 对象操作Optional 流终端操作数组循环集合组合匹配查找信息数字流信息本章小结 集合优化了对象的存储,而流和对象的处理有关。 流是一系列与特定存储机制无关的元素——实际上,流并没有“存储”之说。 利用流,无需迭代集合中的元素,就可以提取和操

JavaEdge全是干货的技术号 3286

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

lambda表达式总结

Lambda基础用法

H785503444的博客 920

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Lambda表达式和Stream流

风吹起了从前,看着天边似在眼前,万般流连~

Wind的博客 1440

掌握这10个Lambda表达式,让你开发效率吊炸天!

熟练运用Lambda表达式能够显著提升代码质量与开发效率,使得代码逻辑更加简明扼要,同时也增强了程序的可读性与维护性。不断学习和实践这些技巧,你的开发效率必将迎来质的飞跃。并且Lambda与Stream一起使用才能发挥他们最大的优点。

王二的博客 1037

Java 8 新特性全面解析:Lambda 表达式、Stream API 等的应用

一、引言Java 8 作为 Java 语言发展历程中的重要版本,带来了诸多革命性的新特性,其中 Lambda 表达式和 Stream API 是最受关注的两大创新。这些新特性不仅借鉴了函数式编程的思想,还针对 Java 开发者在实际开发中遇到的痛点进行了优化,使得 Java 代码在保持面向对象特性的同时,具备了更加简洁、高效和灵活的表达能力。通过 Lambda 表达式,开发者可以以更简洁的方式实现函数式接口,而 Stream API 则为集合数据的处理提供了强大的工具,大大简化了数据处理逻辑。

数字魔方操控师的博客 911

Java流式编程深入解析Lambda表达式与集合操作

例如,从员工列表中按部门分组并计算平均薪资:employees.stream().collect(Collectors.groupingBy(Employee::getDepartment, Collectors.averagingDouble(Employee::getSalary)))。这种设计使得代码更简洁易读,例如从列表中筛选正数并计算平方和:list.stream().filter(x -> x > 0).map(x -> xx).sum()。这些操作消耗流后无法再次使用,是流处理的终点。

soso1029934378的博客 305

《在Java中利用Lambda表达式优化集合处理的五种经典实践》

对集合进行排序是常见的业务需求,Lambda表达式使得实现自定义排序规则变得异常简单。通过`Comparator`接口与Lambda的结合,我们可以轻松定义复杂的排序逻辑。例如,对一个`Person`对象列表按年龄进行降序排序,可以写作:`personList.stream().sorted((p1, p2) -> p2.getAge() - p1.getAge()).collect(Collectors.toList())`。

liyong604的专栏 317

java8——排序

对数据进行排序是平常经常会用到的操作之一,使用Jav8排序可以减少你在排序这方面的代码量,优化你的代码。 测试用例代码 定义个实体类User,拥有姓名name,年龄age,积分credits三个属性,定义一个包含User的集合,用于排序,下面是代码 /* 这里偷个懒,用lombok注解生成实体类getset等一些基本方法 */ @Data @AllArgsConstructor @NoArgsConstructor public class User { private String na.

小屁孩大帅-保密的博客 738

【Java 8新特性】Stream API 和 Lambda 表达式

一文搞懂:【Java 8新特性】Stream API 和 Lambda 表达式的作用

多学、多想、多做 674

【Java8新特性】Optional+Stream+Lambda表达式

【Java8新特性】Optional+Stream+Lambda表达式 文章目录【Java8新特性】Optional+Stream+Lambda表达式学习目标:学习Java8新特性1.OptionalJDK文档资料:2.Stream3.Lambda表达式以下是lambda表达式的重要特征: 学习目标:学习Java8新特性 Optional是什么,有什么用处,一般如何使用 Stream是什么,与传统的集合相比有什么差异不同 lambda主要是实战,编写几个简单是示例:过滤,排序,收集为List(M

HKD的博客 895

JDK8的新特性-Lambda表达式

本文简单认识JDK8的重要新特性之一——Lambda表达式。 在JDK8之前,Java是不支持函数式编程的,所谓的函数编程,即可理解是将一个函数(也称为“行为”)作为一个参数进行传递。通常我们提及得更多的是面向对象编程,面向对象编程是对数据的抽象(各种各样的POJO类),而函数式编程则是对行为的抽象(将行为作为一个参数进行传递)。在JavaScript中这是很常见的一个语法特性,但在Java中将一个函数作为参数传递这却行不通,好在JDK8的出现打破了Java的这一限制。 java8中Lambda表达式

易雁的博客 506

stream流倒序排序_放大招,快使用Java8新特性:Stream+Lambda优化你的代码吧!

Java8的新特性主要是Lambda表达式和流,当流和Lambda表达式结合起来一起使用时,因为流申明式处理数据集合的特点,可以让代码变得简洁易读放大招,流如何简化代码如果有一个需求,需要对数据库查询到的菜肴进行一个处理:筛选出卡路里小于400的菜肴对筛选出的菜肴进行一个排序获取排序后菜肴的名字菜肴:Dish.javapublicclassDish{privateSt...

weixin_34007888的博客 688
上一篇: jquery填充表单
下一篇: 前后端日常开发及Linux命令使用率较高的代码合集
java小安然
博客等级 码龄8年 180粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值