直接上代码。有需要的朋友可以直接拿到项目中使用,非常方便。
首先看调用demo
/**
* @ClassName TreeUtilDemo
* @Author yangruilong
* @Date 2021/8/19 17:47
* @Version 1.0
*/
public class TreeUtilDemo {
public static void main(String[] args) {
// 包含所有的节点数据
List treeVos = new ArrayList<>();
// 这个表示,你的结果集中,为顶级节点,parentId字段的值,如果为null就传null,如果为0就传0,可以随意赋值
Long rootParentId = null;
// 构建树
List treeVos1 =
TreeUtil.buildTree(treeVos, TreeVo::getParentId, TreeVo::getId, TreeVo::setChildren, rootParentId);
// 构建一个升序的树
treeVos1 = TreeUtil.buildAscTree(treeVos, TreeVo::getParentId, TreeVo::getId, TreeVo::setChildren, rootParentId,
TreeVo::getSort);
// 构建一个降序的树
treeVos1 = TreeUtil.buildDescTree(treeVos, TreeVo::getParentId, TreeVo::getId, TreeVo::setChildren,
rootParentId, TreeVo::getSort);
}
@Data
class TreeVo {
private Long id;
private Long parentId;
private List children;
private Integer sort;
private String nodeName;
}
}
然后上工具栏代码
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @ClassName TreeUtil
* @Author yangruilong
* @Date 2021/8/18 16:22
* @Version 1.0
*/
public class TreeUtil {
/***
* 构建树
*
* @param listData
* 需要构建的结果集
* @param parentKeyFunction
* 获取父主键的函数
* @param keyFunction
* 获取主键的函数
* @param setChildrenFunction
* 设置子集的函数
* @param rootParentValue
* 标识为父节点的值
* @return java.util.List
* @author yangruilong
*/
public static List buildTree(List listData, Function parentKeyFunction,
Function keyFunction, BiConsumer> setChildrenFunction, U rootParentValue) {
return buildTree(listData, parentKeyFunction, keyFunction, setChildrenFunction, rootParentValue, null, null);
}
/***
* 构建树,并且对结果集做升序处理
*
* @Version 1.0
* @param listData
* 需要构建的结构集
* @param parentKeyFunction
* 获取父主键的函数
* @param keyFunction
* 获取主键的函数
* @param setChildrenFunction
* 设置子集的函数
* @param rootParentValue
* 标识为父节点的值
* @param sortFunction
* 获取排序字段的值
* @return java.util.List
* @author yangruilong
*/
public static List buildAscTree(List listData, Function parentKeyFunction,
Function keyFunction, BiConsumer> setChildrenFunction, U rootParentValue,
Function sortFunction) {
List resultList =
buildTree(listData, parentKeyFunction, keyFunction, setChildrenFunction, rootParentValue, sortFunction, 0);
return sortList(resultList, sortFunction, 0);
}
/***
* 构建树,并且对结果集做降序处理
*
* @Version 1.0
* @param listData
* 需要构建的结构集
* @param parentKeyFunction
* 获取父主键的函数
* @param keyFunction
* 获取主键的函数
* @param setChildrenFunction
* 设置子集的函数
* @param rootParentValue
* 标识为父节点的值
* @param sortFunction
* 获取排序字段的值
* @return java.util.List
* @author yangruilong
*/
public static List buildDescTree(List listData, Function parentKeyFunction,
Function keyFunction, BiConsumer> setChildrenFunction, U rootParentValue,
Function sortFunction) {
List resultList =
buildTree(listData, parentKeyFunction, keyFunction, setChildrenFunction, rootParentValue, sortFunction, 1);
return sortList(resultList, sortFunction, 1);
}
private static List buildTree(List listData, Function parentKeyFunction,
Function keyFunction, BiConsumer> setChildrenFunction, U rootParentValue,
Function sortFunction, Integer sortedFlag) {
// 筛选出根节点
Map rootKeyMap = new HashMap<>();
// 所有的节点
Map allKeyMap = new HashMap<>();
// 存id:List
Map> keyParentKeyMap = new HashMap<>();
for (T t : listData) {
Comparable key = keyFunction.apply(t);
Comparable parentKey = parentKeyFunction.apply(t);
// 如果根节点标识为null,值也为null,表示为根节点
if (rootParentValue == null && parentKeyFunction.apply(t) == null) {
rootKeyMap.put(key, t);
}
// 根节点标识有值,值相同表示为根节点
if (rootParentValue != null && parentKeyFunction.apply(t).compareTo(rootParentValue) == 0) {
rootKeyMap.put(key, t);
}
allKeyMap.put(key, t);
if (parentKey != null) {
List children = keyParentKeyMap.getOrDefault(parentKey, new ArrayList<>());
children.add(key);
keyParentKeyMap.put(parentKey, children);
}
}
List returnList = new ArrayList<>();
// 封装根节点数据
for (Comparable comparable : rootKeyMap.keySet()) {
setChildren(comparable, returnList, allKeyMap, keyParentKeyMap, setChildrenFunction, sortFunction,
sortedFlag);
}
return returnList;
}
private static void setChildren(Comparable comparable, List childrenList, Map childrenKeyMap,
Map> keyParentKeyMap, BiConsumer> setChildrenFunction,
Function sortFunction, Integer sortedFlag) {
T t = childrenKeyMap.get(comparable);
if (keyParentKeyMap.containsKey(comparable)) {
List subChildrenList = new ArrayList<>();
List childrenComparable = keyParentKeyMap.get(comparable);
for (Comparable c : childrenComparable) {
setChildren(c, subChildrenList, childrenKeyMap, keyParentKeyMap, setChildrenFunction, sortFunction,
sortedFlag);
}
subChildrenList = sortList(subChildrenList, sortFunction, sortedFlag);
setChildrenFunction.accept(t, subChildrenList);
}
childrenList.add(t);
}
private static List sortList(List list, Function sortFunction,
Integer sortedFlag) {
if (sortFunction != null) {
if (sortedFlag == 1) {
return (List)list.stream().sorted(Comparator.comparing(sortFunction).reversed())
.collect(Collectors.toList());
} else {
return (List)list.stream().sorted(Comparator.comparing(sortFunction)).collect(Collectors.toList());
}
}
return list;
}
}