在Java开发中避免不了要查询树形结构,就会有很多人写一大堆for循环来进行查询,其实用java8的新特性Stream流很容易就能实现简洁易懂并且能实现效果。
1.实体类:TreeMenu.java
2.Stream递归组装树形结构
3.Java格式化打印结果
package com.example.treedemo.domain;
import lombok.Builder;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @author ChangXu
* @Version FlyFish V1.0
* @Date 2023/8/39:18
*/
@Data
@Builder
public class TreeMenu implements Serializable {
/**
* 主键id
*/
public Integer id;
/**
* 树形菜单名称
*/
public String name;
/**
* 父id根节点为0
*/
public Integer parentId;
/**
* 子节点信息子集
*/
public List<TreeMenu> childList;
//构造方法
public TreeMenu(Integer id, String name, Integer parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
}
//构造方法
public TreeMenu(Integer id, String name, Integer parentId, List<TreeMenu> childList) {
this.id = id;
this.name = name;
this.parentId = parentId;
this.childList = childList;
}
}
package com.example.treedemo;
import com.alibaba.fastjson2.JSON;
import com.example.treedemo.domain.TreeMenu;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@SpringBootTest
class TreeDemoApplicationTests {
@Test
void contextLoads() {
//组装数据模拟从数据库查询出来
List<TreeMenu> TreeMenus = Arrays.asList(
new TreeMenu(1, "根节点", 0),
new TreeMenu(2, "子节点1", 1),
new TreeMenu(3, "子节点1.1", 2),
new TreeMenu(4, "子节点1.2", 2),
new TreeMenu(5, "根节点1.3", 2),
new TreeMenu(6, "根节点2", 1),
new TreeMenu(7, "根节点2.1", 6),
new TreeMenu(8, "根节点2.2", 6),
new TreeMenu(9, "根节点2.2.1", 7),
new TreeMenu(10, "根节点2.2.2", 7),
new TreeMenu(11, "根节点3", 1),
new TreeMenu(12, "根节点4", 1),
new TreeMenu(13, "根节点4.1", 12),
new TreeMenu(14, "根节点4.2", 13),
new TreeMenu(15, "根节点4.3", 12));
//获取父节点数据
List<TreeMenu> treeList = TreeMenus.stream().filter(m -> m.getParentId() == 0).map(
(m) -> {
m.setChildList(getChildrens(m, TreeMenus));
return m;
}
).collect(Collectors.toList());
System.out.println("-------转换输出json结果-------");
System.out.println(JSON.toJSON(treeList));
}
/**
* 递归查询子节点
* @param menu 根节点
* @param treeMenus 所有子节点
* @return
*/
private List<TreeMenu> getChildrens(TreeMenu menu, List<TreeMenu> treeMenus) {
List<TreeMenu> children = treeMenus.stream().filter(m -> {
return Objects.equals(m.getParentId(), menu.getId());
}).map(
(m) -> {
m.setChildList(getChildrens(m, treeMenus));
return m;
}
).collect(Collectors.toList());
return children;
}
}
[
{
"childList":[
{
"childList":[
{
"childList":[
],
"id":3,
"name":"子节点1.1",
"parentId":2
},
{
"childList":[
],
"id":4,
"name":"子节点1.2",
"parentId":2
},
{
"childList":[
],
"id":5,
"name":"根节点1.3",
"parentId":2
}
],
"id":2,
"name":"子节点1",
"parentId":1
},
{
"childList":[
{
"childList":[
{
"childList":[
],
"id":9,
"name":"根节点2.2.1",
"parentId":7
},
{
"childList":[
],
"id":10,
"name":"根节点2.2.2",
"parentId":7
}
],
"id":7,
"name":"根节点2.1",
"parentId":6
},
{
"childList":[
],
"id":8,
"name":"根节点2.2",
"parentId":6
}
],
"id":6,
"name":"根节点2",
"parentId":1
},
{
"childList":[
],
"id":11,
"name":"根节点3",
"parentId":1
},
{
"childList":[
{
"childList":[
{
"childList":[
],
"id":14,
"name":"根节点4.2",
"parentId":13
}
],
"id":13,
"name":"根节点4.1",
"parentId":12
},
{
"childList":[
],
"id":15,
"name":"根节点4.3",
"parentId":12
}
],
"id":12,
"name":"根节点4",
"parentId":1
}
],
"id":1,
"name":"根节点",
"parentId":0
}
]