使用HutoUtil 中TreeUtil进行树形结构操作(可直接运行)
pom.xml
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.6</version>
</dependency>
实体类
@Data
@Accessors(chain = true)
public class TreeDemo {
private Integer id;
private Integer parentId;
private Integer level;
private String levelName;
private Integer isEfficient;
private Integer isShow;
private String createdBy;
private Date createdDate;
private String updatedBy;
private Date updatedDate;
}
测试类
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.json.JSONUtil;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* TODO 树形结构测试
* @date 2021/12/22 11:41
*/
public class TestDemo {
public static void main(String[] args) {
List<TreeDemo> treeDemoList = new ArrayList<>();
treeDemoList=initTreeDemo();
// 1、将源数据转化为树
List<Tree<Integer>> build = transform(treeDemoList);
//2、通过子节点查找父节点
List<TreeDemo> parentList = childToParent(treeDemoList,build);
//3、通过父节点查找子节点
Tree<Integer> tree= parentToChile(build);
}
/**
* 1:初始化数据
*/
public static List<TreeDemo> initTreeDemo(){
List<TreeDemo> treeDemoList = new ArrayList<>();
TreeDemo treeDemo = new TreeDemo();
treeDemo.setId(1).setParentId(0).setLevel(1).setLevelName("A").setIsEfficient(1).setIsShow(1);
TreeDemo treeDemo1 = new TreeDemo();
treeDemo1.setId(2).setParentId(1).setLevel(2).setLevelName("B").setIsEfficient(1).setIsShow(1);
TreeDemo treeDemo2 = new TreeDemo();
treeDemo2.setId(3).setParentId(2).setLevel(3).setLevelName("C").setIsEfficient(1).setIsShow(1);
TreeDemo treeDemo3 = new TreeDemo();
treeDemo3.setId(4).setParentId(3).setLevel(4).setLevelName("D").setIsEfficient(1).setIsShow(1);
TreeDemo treeDemo4 = new TreeDemo();
treeDemo4.setId(5).setParentId(4).setLevel(5).setLevelName("E").setIsEfficient(1).setIsShow(1);
TreeDemo treeDemo5 = new TreeDemo();
treeDemo5.setId(6).setParentId(0).setLevel(1).setLevelName("A1").setIsEfficient(1).setIsShow(1);
TreeDemo treeDemo6 = new TreeDemo();
treeDemo6.setId(7).setParentId(6).setLevel(2).setLevelName("B1").setIsEfficient(1).setIsShow(1);
TreeDemo treeDemo7 = new TreeDemo();
treeDemo7.setId(8).setParentId(7).setLevel(3).setLevelName("C1").setIsEfficient(1).setIsShow(1);
TreeDemo treeDemo8 = new TreeDemo();
treeDemo8.setId(9).setParentId(8).setLevel(4).setLevelName("D1").setIsEfficient(1).setIsShow(1);
TreeDemo treeDemo9 = new TreeDemo();
treeDemo9.setId(10).setParentId(9).setLevel(5).setLevelName("E1").setIsEfficient(1).setIsShow(1);
TreeDemo treeDemo10 = new TreeDemo();
treeDemo10.setId(11).setParentId(7).setLevel(3).setLevelName("C2").setIsEfficient(1).setIsShow(1);
TreeDemo treeDemo11 = new TreeDemo();
treeDemo11.setId(12).setParentId(8).setLevel(4).setLevelName("D2").setIsEfficient(1).setIsShow(1);
TreeDemo treeDemo12 = new TreeDemo();
treeDemo12.setId(13).setParentId(9).setLevel(5).setLevelName("E2").setIsEfficient(1).setIsShow(1);
treeDemoList.add(treeDemo);
treeDemoList.add(treeDemo1);
treeDemoList.add(treeDemo2);
treeDemoList.add(treeDemo3);
treeDemoList.add(treeDemo4);
treeDemoList.add(treeDemo5);
treeDemoList.add(treeDemo6);
treeDemoList.add(treeDemo7);
treeDemoList.add(treeDemo8);
treeDemoList.add(treeDemo9);
treeDemoList.add(treeDemo10);
treeDemoList.add(treeDemo11);
treeDemoList.add(treeDemo12);
return treeDemoList;
}
/**
* 1.2:将源数据转化为树结构数据
*/
public static List<Tree<Integer>> transform(List<TreeDemo> treeDemoList){
treeDemoList=initTreeDemo();
// 2.配置
TreeNodeConfig config = new TreeNodeConfig();
//默认为id可以不设置
config.setIdKey("id");
//默认为parentId可以不设置
config.setParentIdKey("parentId");
//最大递归深度
config.setDeep(5);
//排序字段
config.setWeightKey("level");
// 3.转树,Tree<>里面泛型为id的类型
List<Tree<Integer>> build = TreeUtil.build(treeDemoList, 0, config, (object, tree) -> {
// 也可以使用 tree.setId(object.getId());等一些默认值
tree.putExtra("id", object.getId());
tree.putExtra("parentId", object.getParentId());
tree.putExtra("level", object.getLevel());
tree.putExtra("levelName", object.getLevelName());
tree.putExtra("isEfficient", object.getIsEfficient());
tree.putExtra("isShow", object.getIsShow());
});
System.out.println("将源数据转化为树:"+JSONUtil.toJsonStr(build));
return build;
}
/**
* @desc 2.1 子节点查找父节点(此功能自己实现可以用treeUtil里面的getParentsName)
*
* 实现思路:1、获取指定节点
* 2、将全部节点转化为map,id做key
* 3、递归循环向上匹配 知道对象为空
*/
public static List<TreeDemo> childToParent(List<TreeDemo> treeDemoList, List<Tree<Integer>> build){
//定义指定节点
TreeDemo treeDemo9 = new TreeDemo();
treeDemo9.setId(10).setParentId(9).setLevel(5).setLevelName("E1").setIsEfficient(1).setIsShow(1);
//通过set添加查找后的实体
final Set<TreeDemo> nodeList = new HashSet<>();
//将源数据转化为map
final Map<Integer, TreeDemo> allMap = treeDemoList.stream().collect(Collectors.toMap(TreeDemo::getId, Function.identity(), (v1, v2) -> v2));
// build.forEach(node -> {
findParent(nodeList, treeDemo9, allMap);
// });
List<TreeDemo> nodes = new ArrayList<>(nodeList);
System.out.println("子节点找父节点:"+JSONUtil.toJsonStr(nodes));
return nodes;
}
/**
* :2.2递归查找父节点
*/
private static void findParent(Set<TreeDemo> nodeList, TreeDemo current, Map<Integer, TreeDemo> allMap) {
if (Objects.nonNull(current)) {
nodeList.add(current);
}
if (Objects.nonNull(current)) {
TreeDemo parent = allMap.get(current.getParentId());
findParent(nodeList, parent, allMap);
}
}
/**
* @desc 通过指定3:节点查找子节点
*/
public static Tree<Integer> parentToChile( List<Tree<Integer>> build){
Tree<Integer> childNode = new Tree<>();
for(Tree node : build){
childNode=TreeUtil.getNode(node,6);
if(Objects.nonNull(childNode)){
break;
}
}
System.out.println("查找父节点及其子节点:"+JSONUtil.toJsonStr(childNode));
return childNode;
}