最近做项目,遇到了很多双层for循环组装数据的情况,有的甚至是三层循环,数据组装比较麻烦,同事看到我有一个三层的for循环,说你这个可以优化成两层,三层嵌套的太深了,数据量大的情况下,性能会比较差。是的,大家都知道for循环嵌套的越深,数据量大的情况下,循环遍历的次数也是成指数级增长的,性能可想而知(虽然当时我做的这个项目的数据量只有几百,没有太大,这也是当时编码的时候直接用了三层for循环的原因,后来还是听从了同事的意见,优化了一波)。虽然当时我知道数据量不是很大,但是作为一个技术人,有可以改进的地方,坚决不能放过任何可以优化的点,这是作为技术人的底线,也是对高质量代码的追求,尽力保证自己写出来的代码都是高效,安全,快速的。后来从这个优化中我体会到了List转Map思想的妙用,性能成几何倍数增加,后来自己又拓展到两层for循环,做了一些测试,发现确实妙不可言,虽然只是一个小小的优化,我觉得有必要记录下来,分享一下自己的心得,方便大家共同学习。废话说了这么多,现在我带大家一步一步的演示,先看一下双层for循环下的性能测试数据:

 public static Map<String, AllUserInfoModel> getTeamBdmMap(List<AllUserInfoModel> allUserInfoModelList, List<Integer> allBdm) {Map<String, AllUserInfoModel> teamBdmMap = new HashMap<>(128);allBdm.forEach(item -> {allUserInfoModelList.forEach(user -> {if (item.equals(user.getSysUserId())) {if (StringUtils.isNotBlank(user.getDepartmentName())) {teamBdmMap.put(user.getDepartmentName(), user);}}});});return teamBdmMap;}public static void main(String[] args) {List<AllUserInfoModel> allUserInfoModelList = new ArrayList<>();List<Integer> allBdm = new ArrayList<>();for (int i = 0; i < 100000; i++) {AllUserInfoModel userInfoModel = new AllUserInfoModel();userInfoModel.setSysUserId(i);userInfoModel.setDepartmentName("测试战队-" + i);allUserInfoModelList.add(userInfoModel);if (i % 100 == 0) {allBdm.add(i);}}long ls = System.currentTimeMillis();getTeamBdmMap(allUserInfoModelList, allBdm);long le = System.currentTimeMillis();System.out.println(le - ls);}

测试十万次的结果为:

以上是我们按照一般的正常List循环两层遍历得到的结果,2543毫秒即2.5s。

下面让我们看一下转map后的测试结果:

public static Map<String, AllUserInfoModel> getTeamBdmMapTest(List<AllUserInfoModel> allUserInfoModelList, List<Integer> allBdm) {Map<String, AllUserInfoModel> teamBdmMap = new HashMap<>(128);Map<Integer, AllUserInfoModel> userMap = allUserInfoModelList.stream().collect(Collectors.toMap(AllUserInfoModel::getSysUserId, user -> user));allBdm.forEach(item -> {AllUserInfoModel user = userMap.get(item);if (Objects.nonNull(user) && StringUtils.isNotBlank(user.getDepartmentName())) {teamBdmMap.put(user.getDepartmentName(), user);}});return teamBdmMap;}public static void main(String[] args) {List<AllUserInfoModel> allUserInfoModelList = new ArrayList<>();List<Integer> allBdm = new ArrayList<>();for (int i = 0; i < 100000; i++) {AllUserInfoModel userInfoModel = new AllUserInfoModel();userInfoModel.setSysUserId(i);userInfoModel.setDepartmentName("测试战队-" + i);allUserInfoModelList.add(userInfoModel);if (i % 100 == 0) {allBdm.add(i);}}long ls2 = System.currentTimeMillis();getTeamBdmMapTest(allUserInfoModelList, allBdm);long le2 = System.currentTimeMillis();System.out.println(le2 - ls2);}

转Map后测试十万次的结果如下:

把allUserInfoModelList转为Map<Integer, AllUserInfoModel> userMap后时间为137毫秒即为0.1秒,两次结果做个对比可以发现后者比前者提高了约250倍的性能,如果更大的数据量,性能更是指数级提升。正是利用了Map的快速查找(算法复杂度O(1)),减少了循环遍历的次数(时间复杂度由O(n)转变为了O(1)),性能才得以百倍提升(不过增加了空间复杂度,此处是空间换时间,需要在内存不紧张的条件下进行,需要结合实际情况选取是否需要转换)。我觉得这是一种思路的转变,只是一个小小的转换,性能却是天差地别,当然,这个要看具体的业务场景,也不能一味的为了用map而用map,根据具体的业务场景需求,选择合适的方法才是最好的。

List转Map思想的妙用相关推荐

  1. 林锐的《软件工程思想》妙语录

    <软件工程思想>是一本篇幅不大的书,近日重读一遍.嬉笑怒骂中感受到了一些难以言表的想法,惟有摘录原文中的妙语,与各位同乐: 我偶尔也担心此书写得太肤浅,内容少得可怜.就象一只鸡在水里扑腾了 ...

  2. 狄克斯特拉算法(Dijkstra)——算法思想及代码实现

    这个算法可是属于真正的老经典算法了,这学期离散数学里学到的唯一一个算法也就是这个Dijkstra算法,这个算法实际上就有贪心算法的味道在里面,即每次都确定一个顶点的最优路径,直到遍历全图.由于本人水平 ...

  3. Java中Object和Map的互转

    背景 有时,我们需要将实体对象转成map,有时,我们需要将map转成实体对象,下面利用反射完成这样的转换 obj转map 思想:利用反射获取对象属性和属性值,设置到map中 /*** 实体对象转成Ma ...

  4. 2019.5.summary

    2019.5.1 CF C. Prefix Sum Primes 感觉CF就是训练妳如何养成对题目强大的YY能力的QAQ 我们构造 如果只有一种,没辙,只能这样放 否则先放一个2,再放一个1 接下来把 ...

  5. 半监督学习之DTC(Semi-supervised Medical Image Segmentation through Dual-task Consistency)

    半监督学习之DTC 不同于MixMatch这类使用"数据增强后的结果一致性(consistency)",改方法使用"任务一致性"来约束模型(正则化).由于第一类 ...

  6. Android面试宝典2022-(停止更新,请看面试专栏)

    Android面试宝典2020-持续更新 一.Java基础 1.java基本数据类型和引用类型 2.object equals和==的区别 equals和hashcode的关系? 3.static关键 ...

  7. Android最全面试题整理、还有Kotlin

    目录 1.理解线程间通信 2.工作者线程(workerThread)与主线程(UI线程)的理解 3.通过Handler在线程间通信的原理 4.子线程发消息到主线程进行更新 UI,除了 handler ...

  8. 【必收藏】台大李宏毅老师课程 | 资源汇总、笔记总结与索引

    2020年7月20日至2020年8月18日,我刷完了台大李宏毅老师的深度学习/机器学习相关课程,我分为了 64 个大课时,记录了 64 篇笔记. 我对于李老师课程感到惊讶又欣喜: 惊讶在于,李老师能把 ...

  9. termite:从零开始的go语言学习生活

    时隔一年.终于下定决心认真的学习一下golang,为此昨天纠结了好久要不要买一个正版的goland,最后还是没舍得买-为什么要学习go呢?如今在当前这家公司已经工作两年,悠哉的生活使我日日堕落-体重长 ...

最新文章

  1. BZOJ 1101: [POI2007]Zap
  2. ajax 载入html后不能执行其中的js解决方法
  3. 10. http 的一些说明及分析工具
  4. 回顾 | Apache Flink Meetup ·上海站(附PPT下载链接)
  5. 地图标识符号大全_资源小结:旅游类地图汇总(8.17版)
  6. 湖州市技师学院的计算机,湖州技师学院
  7. 通用mrp手机必备新手安装包
  8. 什么是静态代理,什么是动态代理
  9. 国密算法概述 SM1、SM2、SM3、SM4、SM7、SM9、ZUC
  10. 黑马程序员—黑马的学习环境没有亲身经历的人是很难体会的!!!
  11. chm打开秒退_无法打开chm文件
  12. 周鸿祎谈乔布斯(张亮)
  13. 不符合直接升级win11?教你怎么直接安装win11系统
  14. 供应链金融之——预付款融资模式
  15. 微信PC端C++技术获取聊天内容,这个技术足以进入腾讯上班!
  16. VS (Visual Studio) 魔兽插件开发工具 AddOn Studio for WOW 1.0 含有LUA编辑
  17. 浅谈NLM非局部均值滤波
  18. PDF转JPG免费软件有什么?这三个软件值得收藏
  19. Spring Cloud升级之路 - Hoxton - 10. 网关重试带Body的请求Body丢失的问题
  20. 哲学家就餐问题的三种避免死锁的解法(PV操作)

热门文章

  1. 蓝牙配对码配置错误_“看yellow 的时候,连错了蓝牙耳机,结果....”哈哈哈哈我笑到村里通网!!...
  2. 【Android 】零基础到飞升 | 构建一个可复用的自定义BaseAdapter
  3. 视频教程-微信小程序项目实战之我画你猜视频课程-微信开发
  4. 明星直播的品牌效应,这几个关键数据你一定要知道!
  5. oracle 中的口令管理,oracle口令文件的管理
  6. 数据库第十四次作业 电子商城项目
  7. java的书写工具哪个好_学习硬笔书法的时候,用那种书写工具比较好?
  8. 基于Echarts实现可视化数据大屏实时监测大数据
  9. java build failed_java - maven build failed:无法在jre或jdk issu中找到Javac编译器
  10. SuperMap iObject常见问题解答集锦(四)