当前位置: 首页 > news >正文

01-线上问题处理-树形结构拼接

1 递归方式实现

1.1 代码

步骤一:一次性获取到所有的数据tisManualCatalogPOS
步骤二:获取到一级节点(parentId为null)
步骤三:递归向下拼接
树的深度很深,导致堆栈越多,可能

生产8K的数据能很明显的看到接口响应慢,<没打印日志>

  private List<ManualTreeVO> buildTree(List<TisManualCatalogPO> tisManualCatalogPOS) {List<ManualTreeVO> treeVOList = Lists.newArrayList();if (CollectionUtils.isEmpty(tisManualCatalogPOS)) {return treeVOList;}List<ManualTreeVO> dataList = tisManualCatalogPOS.stream().map(x -> {ManualTreeVO bean = new ManualTreeVO();bean.setId(x.getId());bean.setName(x.getName());bean.setSort(x.getSort());bean.setType(x.getType());bean.setCode(x.getCode());bean.setParentId(x.getParentId());String filePath = x.getFilePath();// 不包含则拼前缀if (StringUtils.isNotEmpty(filePath) && !filePath.contains(filePathPrefix)) {filePath = filePathPrefix + filePath;}bean.setFilePath(filePath);return bean;}).collect(Collectors.toList());// 拿到所有的一级节点List<ManualTreeVO> firstCatalogList = dataList.stream().filter(x -> Objects.isNull(x.getParentId())).sorted(Comparator.comparing(ManualTreeVO::getSort)).collect(Collectors.toList());for (ManualTreeVO data : firstCatalogList) {// 构建树doBuildTree(dataList, data);treeVOList.add(data);}return treeVOList;}private void doBuildTree(List<ManualTreeVO> hoursCatalogList, ManualTreeVO treeVO) {// 下一级List<ManualTreeVO> childrenList = getChildrenList(hoursCatalogList, treeVO);treeVO.setChildrenList(childrenList);for (ManualTreeVO children : childrenList) {// 有下级if (!CollectionUtils.isEmpty(getChildrenList(hoursCatalogList, children))) {doBuildTree(hoursCatalogList, children);}}}private List<ManualTreeVO> getChildrenList(List<ManualTreeVO> hoursCatalogList, ManualTreeVO treeVO) {// 下一级List<ManualTreeVO> nextList = hoursCatalogList.stream().filter(x -> Objects.equals(treeVO.getCode(), x.getParentId())).sorted(Comparator.comparing(ManualTreeVO::getSort)).collect(Collectors.toList());return nextList;}

1.2 性能

2 非递归方式实现(推荐)

2.1 代码

使用Map,哈希的方式用空间换时间,一次遍历即可拼接成树

    public List<ManualTreeVO> buildTreeNew(String uuid, List<TisManualCatalogPO> tisManualCatalogPOS) {log.info("手册目录-拼接目录 uuid {} {}", uuid, CollectionUtils.isNotEmpty(tisManualCatalogPOS) ? tisManualCatalogPOS.size() : 0);List<ManualTreeVO> roots = Lists.newArrayList();Map<String, ManualTreeVO> nodeMap = new HashMap<>();List<ManualTreeVO> dataList = tisManualCatalogPOS.stream().map(x -> {ManualTreeVO bean = new ManualTreeVO();bean.setId(x.getId());bean.setName(x.getName());bean.setSort(x.getSort());bean.setType(x.getType());bean.setCode(x.getCode());bean.setParentId(x.getParentId());String filePath = x.getFilePath();// 不包含则拼前缀if (StringUtils.isNotEmpty(filePath) && !filePath.contains(filePathPrefix)) {filePath = filePathPrefix + filePath;}bean.setFilePath(filePath);return bean;}).collect(Collectors.toList());// 将所有节点存入映射表for (ManualTreeVO node : dataList) {nodeMap.put(node.getCode(), node);}// 构建树结构for (ManualTreeVO node : dataList) {String parentId = node.getParentId();if (parentId == null || parentId.isEmpty()) {roots.add(node);} else {ManualTreeVO parent = nodeMap.get(parentId);if (parent != null) {parent.addChild(node);} else {// 如果父节点不存在,将其作为根节点roots.add(node);}}}log.info("手册目录-拼接目录 uuid end {}", uuid);return roots;}

2.2 性能

stg日志:3662条数据拼接成树花费时间

3 优劣对比

使用 Map 非递归实现相比递归实现有以下优势:

  1. 避免栈溢出:递归实现在处理深度很大的树时可能导致栈溢出,而非递归实现没有这个问题

  2. 性能更好:非递归实现通常比递归实现有更好的性能,特别是对于大数据集

  3. 更易调试:非递归实现的执行流程更线性,更容易调试和理解

  4. 内存控制:非递归实现可以更好地控制内存使用,特别是在使用迭代器或队列时

  5. 可中断性:非递归实现可以更容易地添加中断条件或超时机制

4 使用建议

  1. 小规模数据:可以使用简单的递归实现,代码更简洁

  2. 大规模数据:推荐使用非递归实现,避免栈溢出风险

  3. 性能关键:使用高效的单次遍历实现,性能最佳

  4. 内存敏感:使用基于栈的实现,内存使用更可控


文章转载自:

http://RLAFe6AT.kkjhj.cn
http://KW08KeqX.kkjhj.cn
http://3c6IL1tt.kkjhj.cn
http://yRwZTAax.kkjhj.cn
http://hOjzu0IT.kkjhj.cn
http://UFbT7UD2.kkjhj.cn
http://Jjx0wwo7.kkjhj.cn
http://WxOWUX6M.kkjhj.cn
http://yIIbhaKh.kkjhj.cn
http://YcLS75Nw.kkjhj.cn
http://QVZL9Tm5.kkjhj.cn
http://J4MvZ5d2.kkjhj.cn
http://umNMaV3E.kkjhj.cn
http://6U6E07HV.kkjhj.cn
http://IhGkPc4x.kkjhj.cn
http://xn9aIdhw.kkjhj.cn
http://GGIcQ95d.kkjhj.cn
http://nsz2qtZp.kkjhj.cn
http://jxDJFaRy.kkjhj.cn
http://woQXaqcW.kkjhj.cn
http://aSHN45kM.kkjhj.cn
http://hildtVT3.kkjhj.cn
http://LijGsim0.kkjhj.cn
http://NRZV51rF.kkjhj.cn
http://G89K0Ib9.kkjhj.cn
http://ELYq5iPT.kkjhj.cn
http://z1ShScaF.kkjhj.cn
http://2yIRjhKh.kkjhj.cn
http://WRzgmyvl.kkjhj.cn
http://wDl1RFhS.kkjhj.cn
http://www.dtcms.com/a/369802.html

相关文章:

  • uniapp | 解决组件样式不生效问题
  • 尚硅谷宋红康JVM全套教程(详解java虚拟机)
  • uniapp基础组件概述
  • C++和OpenGL实现3D游戏编程【连载30】——文字的多行显示
  • 使用UniApp实现下拉框和表格组件页面
  • 人工智能学习:基于seq2seq模型架构实现翻译
  • Day12--HOT100--23. 合并 K 个升序链表,146. LRU 缓存,94. 二叉树的中序遍历
  • Hive on Tez/Spark 执行引擎对比与优化
  • 03.缓存池
  • 突破反爬限制:动态IP轮换策略与实现
  • stunnel实现TCP双向认证加密
  • C#实现导入CSV数据到List<T>的完整教程
  • 安卓学习 之 按钮点击事件
  • Nmap网络扫描工具详细使用教程
  • 持续集成和持续交付 (CI/CD) 工具——Jenkins
  • 微信小程序携带token跳转h5, h5再返回微信小程序
  • ISO/IEC 27001 第八章 运行
  • 苍穹外卖项目实战(day-5完整版)-记录实战教程及问题的解决方法
  • GO语言的主要语法和特性
  • ubuntu 系統使用過程中黑屏問題分析
  • JavaScript 入门精要:从变量到对象,构建稳固基础
  • Go语言设计模式(三)抽象工厂模式
  • SDRAM-08 数据手册解读
  • [光学原理与应用-436]:晶体光学 - 各向同性与各向异性是描述材料物理性质随方向变化特性
  • python:如何生成 TA-Lib .whl 安装包?
  • AD渗透中服务账号相关攻击手法总结(Kerberoasting、委派)
  • 从Java全栈到Vue3实战:一次真实面试中的技术探索
  • python graphviz中文测试
  • 【VoNR】VoNR 不等于 VoLTE on 5G
  • 基于 GEE 批量下载 Landsat8 地表温度(LST)数据