日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2024/9/27 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 树形结构递归初始化(父节点,统计字段等) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 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;} }

總結

以上是生活随笔為你收集整理的树形结构递归初始化(父节点,统计字段等)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。