一.定义树形结构对象
@Data
public class TreeData<T> implements Serializable {
private Long id;
@TableField(exist = false)
private String name;
@TableField(exist = false)
private Long pId;
@TableField(exist = false)
private String type;
@TableField(exist = false)
private String idType;
@TableField(exist = false)
private List<T> children;
}
二.定义树形工具类支持泛型
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TreeUtil {
/**
* 将平行的树,转化为一颗有层级关系的树
*
* @param list
* @param pId
* @return
*/
public static <T extends TreeData> List<T> getTreeList(List<T> list, Long pId) {
if (list == null) {
return null;
}
//获取所有头节点
List<T> rootNode = new ArrayList<>();
for (T treeData : list) {
if (treeData.getId().equals(pId)) {
rootNode.add(treeData);
}
}
//头节点不存在的情况
if (rootNode.size() == 0) {
return getChild(pId, list);
}
//头节点存在的情况
for (T treeData : rootNode) {
Long id = treeData.getId();
treeData.setChildren(getChild(id, list));
}
return rootNode;
}
public static <T extends TreeData> List<T> getChild(Long id, List<T> list) {
//找到id节点子节点
List<T> childList = new ArrayList<>();
for (T treeData : list) {
if (treeData.getPId().equals(id)) {
childList.add(treeData);
}
}
//给子节点设置子节点
for (T treeData : childList) {
id = treeData.getId();
//递归
treeData.setChildren(getChild(id, list));
}
if (childList.size() == 0) {
return null;
}
return childList;
}
public static <T extends TreeData> List<Long> getChildIds(Long id, List<T> list, List<Long> childIds) {
//找到id节点子节点
List<T> childList = new ArrayList<>();
for (T treeData : list) {
if (treeData.getPId().equals(id)) {
childList.add(treeData);
childIds.add(treeData.getId());
}
}
//给子节点设置子节点
for (T treeData : childList) {
id = treeData.getId();
//递归
getChildIds(id, list, childIds);
}
if (childList.size() == 0) {
return null;
}
return childIds;
}
public static <T extends TreeData> List<T> getTreeExcludeMyself(Long id, Long excludeId, List<T> list) {
//找到id节点子节点
List<T> childList = new ArrayList<>();
for (T treeData : list) {
if (treeData.getPId().equals(id)) {
//不包含excludeId级别的级别和子级别
if (treeData.getId().equals(excludeId)) {
continue;
}
childList.add(treeData);
}
}
//给子节点设置子节点
for (TreeData treeData : childList) {
id = treeData.getId();
//递归
treeData.setChildren(getTreeExcludeMyself(id, excludeId, list));
}
if (childList.size() == 0) {
return null;
}
return childList;
}
public static <T extends TreeData> List<Long> getChildIds(Long id, List<T> list) {
//找到id节点子节点
List<T> childList = new ArrayList<>();
List<Long> childIds = new ArrayList<>();
for (T treeData : list) {
if (treeData.getPId().equals(id)) {
childList.add(treeData);
childIds.add(treeData.getId());
}
}
//给子节点设置子节点
for (TreeData treeData : childList) {
id = treeData.getId();
//递归
treeData.setChildren(getChild(id, list));
}
if (childList.size() == 0) {
return null;
}
return childIds;
}
/**
* 获取指定层级的树
*
* @param treeList
* @param level
* @return
*/
public static <T extends TreeData> List<T> getTreeNodeOnLevel(List<T> treeList, int level) {
if (treeList == null && treeList.size() == 0) {
return new ArrayList<>();
}
ArrayList<T> treeListOnLevel = new ArrayList<>();
//调用递归方法
treeList = TreeUtil.recursionQueryTree(treeList, treeListOnLevel, 0, level);
return treeList;
}
/**
* 递归查所有指定层级的树节点
*
* @param treeList
* @param treeListOnLevel
* @param currentLevel
* @param level
* @return
*/
private static <T extends TreeData> List<T> recursionQueryTree(List<T> treeList, List<T> treeListOnLevel, int currentLevel, int level) {
currentLevel++;
//递归循环查询指定层级树
for (T treeData : treeList) {
if (currentLevel == level) {
treeListOnLevel.add(treeData);
continue;
}
//递归
if (treeData.getChildren() == null || treeData.getChildren().size() == 0) {
continue;
}
recursionQueryTree(treeData.getChildren(), treeListOnLevel, currentLevel, level);
}
return treeListOnLevel;
}
/**
* 统计一颗树的深度
*
* @param treeList
* @return
*/
public static <T extends TreeData> int getTreeLevel(List<T> treeList) {
if (treeList == null || treeList.size() == 0) {
return 0;
}
//调用递归统计方法
return TreeUtil.recursionCount(treeList, 0, 0);
}
private static <T extends TreeData> int recursionCount(List<T> treeList, int currentlevel, int maxlevel) {
currentlevel++;
//当当前层级大于目前最大层级时覆盖
if (currentlevel > maxlevel) {
maxlevel = currentlevel;
}
//递归遍历节点
for (T treeData : treeList) {
//如果子节点为空不进行递归
if (treeData.getChildren() == null || treeData.getChildren().size() == 0) {
continue;
}
//递归
maxlevel = recursionCount(treeData.getChildren(), currentlevel, maxlevel);
}
return maxlevel;
}
/**
* 获取指定id在此树中的层级位置
*
* @param list 要遍历的树
* @param id 要寻找的节点Id
* @param rankCount 层级统计器,传入0即可
* @return
*/
public static <T extends TreeData> Map<String, Object> getNode(List<T> list, Long id, Integer rankCount) {
TreeData node = null;
//计数器加一
rankCount++;
Map<String, Object> map = new HashMap<>();
map.put("node", node);
map.put("rankCount", rankCount);
//如果传入的树为0或返回层级0
if (list == null || list.size() == 0) {
map.put("rankCount", 0);
return map;
}
//遍历树
for (T treeData : list) {
if (treeData.getId().equals(id)) {
map.put("node", treeData);
return map;
}
if (treeData.getChildren() == null || treeData.getChildren().size() == 0) {
continue;
}
//递归
Map<String, Object> map1 = getNode(treeData.getChildren(), id, rankCount);
if (map1.get("node") != null) {
return map1;
}
}
//如果传入的节点是不存在的,返回层级0
map.put("rankCount", 0);
return map;
}
/**
* 把树形结构,解构为列表
*
* @param root 父节点
* @return 子节点列表
*/
public static <T extends TreeData> List<T> unLevelTree(T root) {
List<T> childrenList = unConvert(root.getChildren());
return childrenList;
}
private static <T extends TreeData> List<T> unConvert(List<T> childrenList) {
List<T> tempList = new ArrayList<>();
childrenList.forEach(item -> {
tempList.add(item);
if (item.getChildren() != null && item.getChildren().size() > 0) {
tempList.addAll(unConvert(item.getChildren()));
}
});
return tempList;
}
}
三.使用
//步骤二:封装子级树
List<TreeData> childTreeList = TreeUtil.getTreeList(allList, orgDefaultId);//企业级别默认为-1
if (CollectionUtils.isEmpty(childTreeList)) {
parentTreeData.setChildren(new ArrayList<>());
deptTreeList.add(parentTreeData);
return deptTreeList;
}