我正在参加「掘金·启航计划」
package com.hkinfo.support.utils;
import org.apache.poi.ss.formula.functions.T;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @Description: 传入List构建Tree数据
* @author: Freedom
* @QQ: 1556507698
* @date:2022/7/14 9:10
*/
public class TreeUtils<T, K> {
private final List<T> list;
private final Function<? super T, ? extends K> idFunc;
private final Function<? super T, ? extends K> pidFunc;
private final TreeChildConsumer<T> setChildren;
/**
* 调用方法 TreeUtils<SysDept, String> tree = new TreeUtils<>(depts, SysDept::getDeptId, SysDept::getParentId, SysDept::setChildren);
* System.out.println(JSON.toJSONString(tree.build()));
* @param list 需要转换的list数据
* @param idFunc 节点的id
* @param pidFunc 节点的父id
* @param setChildren 注入子节点的方法
*/
public TreeUtils(List<T> list,
Function<? super T, ? extends K> idFunc,
Function<? super T, ? extends K> pidFunc,
TreeChildConsumer<T> setChildren) {
this.list = list;
this.idFunc = idFunc;
this.pidFunc = pidFunc;
this.setChildren = setChildren;
}
/**
* 开始构建节点
*
* @return list 所有根节点的集合
*/
public List<T> build() {
List<T> data = this.list;
if (data.isEmpty()) {
return null;
}
List<T> rootList = new ArrayList<>();
for (T root : data) {
if (data.stream().noneMatch(item -> idFunc.apply(item).equals(pidFunc.apply(root)))) {
rootList.add(buildChild(root));
}
}
return rootList;
}
/**
* 使用递归开始构建子节点
*
* @param parent 父节点
* @return T 构建好当前节点的所有子节点
*/
protected T buildChild(T parent) {
List<T> children = new ArrayList<>();
for (T t : list) {
if (idFunc.apply(parent).equals(pidFunc.apply(t))) {
children.add(buildChild(t));
}
}
// 找到所有子节点后将其注入到父节点
setChildren.accept(parent, children);
return parent;
}
@FunctionalInterface
public interface TreeChildConsumer<T> {
void accept(T t, List<T> tList);
}
}
使用方法
TreeUtils<RuleDict, String> tree = new TreeUtils<>(list, RuleDict::getId, RuleDict::getParentId, RuleDict::setChildren);
tree.build();