java树形结构工具包

47 阅读2分钟

/**

  • 遍历原始数据列表,按照给定的父ID获取函数对节点进行分组,构建一个以父ID为键、子节点列表为值的映射表。
  • 这样可以方便地根据节点的子ID快速找到其所有子节点。
  • 初始化一个空的结果列表,用于存放最终形成的树形结构。
  • 遍历原始数据列表中的每个节点:
  • a. 使用子ID获取函数获取当前节点的子ID。
  • b. 从映射表中查找与当前节点子ID对应的子节点列表。如果存在且非空,说明当前节点有子节点,
  •  则使用给定的子节点设置消费者将子节点列表赋给当前节点。
    
  • c. 使用父ID获取函数获取当前节点的父ID。
  • d. 根据传入的根节点标识判断当前节点是否应被加入结果列表:
  •  - 如果根节点标识为null,表示返回整个树形结构,因此将所有节点都加入结果列表;
    
  •  - 否则,只有当当前节点的父ID等于根节点标识时,才将当前节点加入结果列表。
    
  • 最终返回构建好的树形结构列表。 / /*
    • 将数据转换为树状数据

    • @param list 原始数据列表

    • @param rootTrait 根节点标识(如果为null,则返回所有节点组成的树)

    • @param parentValueGetter 获取节点父ID的函数

    • @param childValueGetter 获取节点子ID的函数

    • @param childSetter 设置节点子节点列表的消费者

    • @param 节点类型

    • @param ID类型

    • @return 树形数据 */ public static <T, R> List buildTree(List list, R rootTrait, Function<T, R> parentValueGetter, Function<T, R> childValueGetter, BiConsumer<T, List> childSetter) {

      Map<R, List> nodesByParentId = list.stream() .collect(Collectors.groupingBy(parentValueGetter));

      List result = new ArrayList<>(); for (T node : list) { R nodeId = childValueGetter.apply(node); List children = nodesByParentId.get(nodeId);

       if (CollUtil.isNotEmpty(children)) {
           childSetter.accept(node, children);
       }
      
       R parentNodeId = parentValueGetter.apply(node);
       if (rootTrait == null || Objects.equals(parentNodeId, rootTrait)) {
           result.add(node);
       }
      

      }

      return result; }