树形结构递归初始化(父节点,统计字段等)

文章目录

  • 1.核心思想:
  • 2.核心方法实现:
  • 3.完整代码如下
    • 3.1. 树形实体
    • 3.2. 完整操作

1.核心思想:

1.先将每个节点按层级进行分组成map,并记录最大层级;
2.层级自下而上的递归,赋值父节点和统计金额类的字段;

2.核心方法实现:

    //层级分组map (key:层级;value:该层级下的节点集合)private Map<Integer, List<TreeNodeBO>> hierarchyMap = new HashMap<>();/*** 初始化父节点、金额、数量 <br>** @param hierarchy: 最大层级* @return void* @see*/private void initTreeNodeBO(Integer hierarchy) {if (hierarchy == 0) { //0层级无父级层级 、跳出递归return;}List<TreeNodeBO> currentHierarchy = hierarchyMap.get(hierarchy);//当前层级List<TreeNodeBO> parentHierarchy = hierarchyMap.get(--hierarchy);//当前层级的 父级层级if (CollectionUtils.isNotEmpty(currentHierarchy)) {parentHierarchy.stream().forEach(parent -> {//当前父节点 的子节点集合List<TreeNodeBO> childNode = currentHierarchy.stream().filter(child -> child.getCode().indexOf(parent.getCode()) == 0).collect(Collectors.toList());childNode.stream().forEach(child -> child.setParentCode(parent.getCode()));//子节点集合设置 parentCodeBigDecimal childAmount = childNode.stream().map(TreeNodeBO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);//子节点金额和BigDecimal childQty = childNode.stream().map(TreeNodeBO::getQty).reduce(BigDecimal.ZERO, BigDecimal::add);//子节点数量和parent.setAmount(parent.getAmount().add(childAmount));parent.setQty(parent.getQty().add(childQty));});}initTreeNodeBO(hierarchy);}

3.完整代码如下

我的节点数据来自excel的导入(excel的导入导出可以看:Springboot 下 EasyExcel 的数据导入导出)

节点数据按层级分组后的是 hierarchyMap ,是在 invoke() 方法中初始化的;

核心思想的实现,只需要看 doAfterAllAnalysed()方法

3.1. 树形实体

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ContentRowHeight(15)//内容单元格高度
@HeadRowHeight(15)//表头单元格高度
@ColumnWidth(10)//单元格宽度
public class ExcelBO {//编码@NotEmpty@ExcelProperty(index = 0,value = {"编码"})private String code;//名称@NotEmpty@ExcelProperty(index = 1,value = {"名称"})private String name;//单位@NotEmpty@ExcelProperty(index = 2,value = "单位")private String unit;//数量@NotNull@ExcelProperty(index = 3,value = "数量")private BigDecimal qty;//单价@NotNull@ExcelProperty(index = 4,value = "单价")private BigDecimal price;//生产日期@NotNull@ExcelProperty(index = 5,value = "生产日期")private LocalDateTime dateInProduced;//备注@ExcelProperty(index = 6,value = "备注")private String remake;}
@Data
@ToString(callSuper = true)
public class TreeNodeBO extends ExcelBO {//父级编码private String parentCode;//总价值private BigDecimal amount;//层级( 0:第一层  ; 1:第二层 ; 3:第三层)private Integer hierarchy ;//子节点集合private List<TreeNodeBO> childs;}

3.2. 完整操作

/*** 解析监听类 <br>** @author lls* @version 1.0.0* @date 2021/5/19*/
@Slf4j
public class ExcelReadListener extends AnalysisEventListener<ExcelBO> {private Gson gson = new Gson();//层级分组map (key:层级;value:该层级下的节点集合)private Map<Integer, List<TreeNodeBO>> hierarchyMap = new HashMap<>();//最大层级private Integer maxHierarchy = -1;//编码层级分隔符private static String splitStr = "-";/*** 每行解析动作 <br>** @param data:* @param context:* @return void* @see*/@Overridepublic void invoke(ExcelBO data, AnalysisContext context) {context.readWorkbookHolder().getReadWorkbook().setAutoTrim(true);//读取进datalog.info("当前解析行数据,data :{} ", gson.toJson(data));//todo 业务字段校验(长度,非空等) =》(service层 进行@valid校验)TreeNodeBO treeNodeBO = new TreeNodeBO();BeanUtils.copyProperties(data, treeNodeBO);Integer hierarchy = countHierarchy(treeNodeBO.getCode()); //t层级结构 = code中 splitStr 出现的次数maxHierarchy = Math.max(maxHierarchy, hierarchy);//最大层级treeNodeBO.setHierarchy(hierarchy);//todo  赋值父节点的空属性,用于 递归计算 (想办法去掉这段,太傻了)↓↓↓↓↓↓↓↓↓if (null != treeNodeBO.getPrice() && null != treeNodeBO.getQty()) {treeNodeBO.setAmount(treeNodeBO.getPrice().multiply(treeNodeBO.getQty()));//总金额 = 单价 * 数量} else {treeNodeBO.setAmount(BigDecimal.ZERO);}if (null == treeNodeBO.getQty()) {treeNodeBO.setQty(BigDecimal.ZERO);}//todo  ↑↑↑↑↑↑↑List<TreeNodeBO> nodeList = Optional.ofNullable(hierarchyMap.get(hierarchy)).orElse(new ArrayList<>());nodeList.add(treeNodeBO);hierarchyMap.put(treeNodeBO.getHierarchy(), nodeList);}/*** 解析完成后动作 <br>** @param context:* @return void* @see*/@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {log.info("解析到的所有数据集合,excelBOList :{} ", gson.toJson(hierarchyMap));initTreeNodeBO(maxHierarchy);log.info("解析后的所有数据集合,excelBOList :{} ", gson.toJson(hierarchyMap));}/*** 初始化父节点、金额、数量 <br>** @param hierarchy: 最大层级* @return void* @see*/private void initTreeNodeBO(Integer hierarchy) {if (hierarchy == 0) { //0层级无父级层级 、跳出递归return;}List<TreeNodeBO> currentHierarchy = hierarchyMap.get(hierarchy);//当前层级List<TreeNodeBO> parentHierarchy = hierarchyMap.get(--hierarchy);//当前层级的 父级层级if (CollectionUtils.isNotEmpty(currentHierarchy)) {parentHierarchy.stream().forEach(parent -> {//当前父节点 的子节点集合List<TreeNodeBO> childNode = currentHierarchy.stream().filter(child -> child.getCode().indexOf(parent.getCode()) == 0).collect(Collectors.toList());childNode.stream().forEach(child -> child.setParentCode(parent.getCode()));//子节点集合设置 parentCodeBigDecimal childAmount = childNode.stream().map(TreeNodeBO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);//子节点金额和BigDecimal childQty = childNode.stream().map(TreeNodeBO::getQty).reduce(BigDecimal.ZERO, BigDecimal::add);//子节点数量和parent.setAmount(parent.getAmount().add(childAmount));parent.setQty(parent.getQty().add(childQty));});}initTreeNodeBO(hierarchy);}/*** 计算节点层级结构(层级结构 = 分隔符出现的次数) <br>** @param code: 编码* @return java.lang.Integer* @see*/private static Integer countHierarchy(String code) {int before = code.length();int after = code.replace(splitStr, "").length();return before - after;}/*** 每个sheet页的头行触发函数 <br>** @param headMap:* @param context:* @return void* @see*/@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {log.info("解析到一条头数据:{}", gson.toJson(headMap));//todo 校验excel模板的正确性//todo 通过 ExcelBO.class 获取field域上ExcelProperty注解。与headMap对比}/*** 发生异常时触发函数 <br>** @param exception:* @param context:* @return void* @see*/@Overridepublic void onException(Exception exception, AnalysisContext context) throws Exception {log.info("捕捉到一条异常:{}", exception);//todo 记录并跳过错误行,返回前端成功的条数throw exception;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/515758.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云原生体系下的技海浮沉与理论探索

来源 | 阿里巴巴中间件责编 | 晋兆雨头图 | 付费下载于视觉中国概述

比GPU性能提升5倍阿里云含光800云服务器正式商用

含光800云服务器&#xff0c;配备阿里平头哥自研神经网络加速芯片含光800&#xff0c;提供全球最高单芯片AI推理性能&#xff0c;有着同类处理器的数十倍性能&#xff1b;并针对业务场景做了深度优化&#xff0c;广泛适用于图像搜索、场景识别、视频内容识别、自然语言处理等业…

阿里研发效能数据知多少

2020 年 3 月阿里云云效平台发布了阿里内部 4 万开发者的研发效能数据报&#xff0c;数据显示阿里代码量和交付表现一路飙升&#xff0c;2020 财年代码行数共新增 15 亿&#xff0c;修改重构代码总行数 4 亿&#xff0c;疫情期间新增代码行 2.9 亿&#xff1b;3 天开发出健康码…

软件设计师 -主观题总结

文章目录1.数据流图1.1.补充外部实体名称1.2.补充数据存储1.3. 补充数据流图&#xff0c;缺失数据流图、起点、终点1.4.选考2.数据库设计&#xff08;ER图&#xff09;2.1.补充中联系关联的对象及联系的类型&#xff08;概念模式设计&#xff09;2.2.补充逻辑结构设计2.3.选考3…

春招抢跑丨腾讯新年放大“招”!超3000+岗位!

虽然离春节仅剩 1 个月的时间&#xff0c;大厂依旧没有停止招人。就在上周&#xff0c;腾讯官宣新年大扩招&#xff0c;放出 3000 多个岗位需求&#xff01;我们查看了腾讯的招聘数据发现&#xff0c;除了大量招聘运营人员&#xff0c;你猜&#xff0c;他们还在批量招聘什么岗位…

达梦数据库连接(单机、多实例、多数据源版本)

文章目录1. 基础版本2. 多实例版本3. 多数据源达梦多实例1. 基础版本 spring:datasource:driver-class-name: dm.jdbc.driver.DmDriverurl: jdbc:dm://192.168.xxx.86:xxx/DAMENG?serverTimezoneGMT%2B8username: usernamepassword: password2. 多实例版本 spring:datasourc…

对话阿里云MVP裔隽跨界半生,不改赤子心

云栖号资讯&#xff1a;【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01; 简介&#xff1a; 我从没想过会用“少年感”来形容一位40岁的商界人士。裔隽在很多时候像一位人生导师&#xff0c;儒雅随和&…

从 2018 年 Nacos 开源说起

2018 年夏天 国内微服务开源 领域&#xff0c;迎来了一位新成员。此后&#xff0c;在构建微服务注册中心和配置中心的过程中&#xff0c;国内开发者多了一个可信赖的选项。 Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台(官方网站)…

用三国杀讲分布式算法,舒适了吧?

来源 | 悟空聊架构头图 | 付费下载于视觉中国点击播放&#xff0c;看文效果更佳&#xff01;东汉末年&#xff0c;袁绍作为盟主&#xff0c;汇合了十八路诸侯一起攻打董卓。在讲解之前&#xff0c;我们先聊下分布式协议和算法整体脉络。现在很多开发同学对分布式的组件怎么使用…

软件设计师 - UML图

文章目录总览UML图关系活动图通信图用例图类图 对象图顺序图状态图组件图总览 UML图关系 包含&#xff1a; 扩展&#xff1a; 泛化&#xff1a; 用例的泛化&#xff1a;把可选行为从必须行为中分离出来&#xff1b; 参与者的泛化&#xff1a;可以完成参与者的同样的任务&am…

SpringBoot 使用宝兰德中间件替换tomcat运行部署+控制台部署

文章目录1. 排除tomcat依赖2. 集成宝兰德依赖3. 项目打包方式4. 支持war部署配置5. 控制台部署1. 排除tomcat依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions>…

戚俊:可能是最懂架构的投资人

云栖号资讯&#xff1a;【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01; 简介&#xff1a; 戚俊的快速成长离不开恰逢其时的机遇和委以重任的伯乐&#xff0c;毕业一两年受邀创业。当腻了CTO&#xf…

除了 Docker,我们还有哪些选择?

来源 | CSDN编译 | 弯月 责编 | 张文头图 | CSDN下载于视觉中国【编者按】所谓三十年河东&#xff0c;三十年河西&#xff0c;曾经在容器领域叱咤风云的 Docker 如今已风光不再。抛开情怀&#xff0c;我们不得不承认&#xff0c;Docker 已经被后浪拍死在沙滩上了……大约 4 年前…

达梦数据库驱动

<!-- 达梦数据库驱动--><dependency><groupId>com.dameng</groupId><artifactId>DmJdbcDriver18</artifactId><version>8.1.2.79</version></dependency>

阿里云李飞飞:今年将帮1000家企业“去O”,完成10000套传统数据仓库上云

阿里云直播回放头号云话题直播回放 “今年将帮1000家企业去O&#xff0c;完成10000套传统数据仓库上云。”6月9日&#xff0c;阿里云数据库负责人李飞飞在阿里云峰会上表示&#xff0c;经过多年技术演进&#xff0c;传统数据库上云已进入大规模攻坚阶段。 达摩院数据库首席科学…

系统架构设计师 - 23种设计模式(GOF)

文章目录总览创建型&#xff08;5种&#xff09;工厂方法 Factory Method抽象工厂 Abstract Factory生成器模式 Builder原型模式 Prototype单例模式 Singleton结构型&#xff08;7种&#xff09;适配器 Adapter桥接 Bridge组合模式 Composite装饰者模式 Decorator外观模式 Faca…

如何优雅的理解HBase和BigTable

云栖号资讯&#xff1a;【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01; 学习 HBase 最难的地方在于要让你的脑子真正理解它是什么。 HBase&#xff1a;Google BigTable 的开源实现 我们经常会把关…

如何使用Trie树,设计实践Google一样的输入提示功能

来源 | 搜索技术责编 | 小白Google和百度都支持输入提示功能&#xff0c;辅助你快速准确的输入想要的内容。如下&#xff1a;输入“五一”&#xff0c;会提示“五一劳动节”等。那如何实现谷歌这样的输入提示功能呢&#xff1f;分析下输入提示的功能需求当输入前面的词A&#x…

计算机与网络

文章目录1.计算机组成2.操作系统进程管理存储管理设备管理文件管理3.数据库系统关系代数数据仓库4.计算机网络1.计算机组成 计算机组成&#xff1a;控制器、运算器、存储设备、输入设备、输出设备。 控制器功能程序计数器&#xff08;PC&#xff09;下条要执行指令的地址指令…