参考资料
import lombok.Builder;
import lombok.Data;
import java.util.List;
@Data
@Builder
public class Menu {
// 菜单id
public Integer id;
// 菜单名称
public String name;
// 菜单父级id
public Integer parentId;
// 菜单子级id列表
public List<Menu> childList;
public Menu(Integer id, String name, Integer parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
}
public Menu(Integer id, String name, Integer parentId, List<Menu> childList) {
this.id = id;
this.name = name;
this.parentId = parentId;
this.childList = childList;
}
}
private List<Menu> queryDataFromDB() {
// 模拟从数据库查询得到数据
return Arrays.asList(
new Menu(1, "根节点1", 0),
new Menu(2, "子根节点1", 1),
new Menu(3, "子节点1.1", 2),
new Menu(4, "子节点1.2", 2),
new Menu(5, "子节点1.3", 2),
new Menu(6, "子根节点2", 1),
new Menu(7, "子节点2.1", 6),
new Menu(8, "子节点2.2", 6),
new Menu(9, "子节点2.2.1", 8),
new Menu(10, "子节点2.2.2", 8),
new Menu(11, "子根节点3", 1),
new Menu(12, "子节点3.1", 11),
new Menu(13, "根节点2", 0),
new Menu(14, "子根节点1", 13),
new Menu(15, "子根节点2", 13)
);
}
public void run(String... args) {
List<Menu> menuList = this.queryDataFromDB();
List<Menu> resultList = menuList.stream()
// 过滤出根节点
.filter(menu -> menu.getParentId() == 0)
.peek(menu -> menu.setChildList(this.getChildList(menu, menuList)))
.collect(Collectors.toList());
// 最终得到树形结构数据
System.out.println(resultList);
}
private List<Menu> getChildList(Menu rootMenu, List<Menu> menuList) {
return menuList.stream()
// 过滤出ParentId和指定的id相等的数据
.filter(menu -> Objects.equals(menu.getParentId(), rootMenu.getId()))
// 递归调用
.peek(menu -> menu.setChildList(this.getChildList(menu, menuList)))
.collect(Collectors.toList());
}
注意
// ...
.peek(menu -> menu.setChildList(this.getChildList(menu, menuList)))
// ...
是下面这种写法的一种更简单的写法
// ...
.map(menu -> {
menu.setChildList(this.getChildList(menu, menuList));
return menu;
})
// ...
[
{
"id": 1,
"name": "根节点1",
"parentId": 0,
"childList": [
{
"id": 2,
"name": "子根节点1",
"parentId": 1,
"childList": [
{
"id": 3,
"name": "子节点1.1",
"parentId": 2,
"childList": []
},
{
"id": 4,
"name": "子节点1.2",
"parentId": 2,
"childList": []
},
{
"id": 5,
"name": "子节点1.3",
"parentId": 2,
"childList": []
}
]
},
{
"id": 6,
"name": "子根节点2",
"parentId": 1,
"childList": [
{
"id": 7,
"name": "子节点2.1",
"parentId": 6,
"childList": []
},
{
"id": 8,
"name": "子节点2.2",
"parentId": 6,
"childList": [
{
"id": 9,
"name": "子节点2.2.1",
"parentId": 8,
"childList": []
},
{
"id": 10,
"name": "子节点2.2.2",
"parentId": 8,
"childList": []
}
]
}
]
},
{
"id": 11,
"name": "子根节点3",
"parentId": 1,
"childList": [
{
"id": 12,
"name": "子节点3.1",
"parentId": 11,
"childList": []
}
]
}
]
},
{
"id": 13,
"name": "根节点2",
"parentId": 0,
"childList": [
{
"id": 14,
"name": "子根节点1",
"parentId": 13,
"childList": []
},
{
"id": 15,
"name": "子根节点2",
"parentId": 13,
"childList": []
}
]
}
]