构建 树工具类
public class TreeUtil {
public static List<SysMenuDTO> listWithTree(List<SysMenuDTO> menuDTOList) {
// 1. 先查出所有分类数据
// 2. 找出所有一级分类
// 在映射到每个一级分类 添加它的子分类类
return menuDTOList.stream()
.filter(o -> o.getParentId() == -1)
// 给每个一级分类加子分类
.peek(o -> o.setChildren(getChildCategoryList(o, menuDTOList)))
// 排序
.sorted(Comparator.comparingInt(SysMenuDTO::getSort))
// 收集
.collect(Collectors.toList());
}
// 根据当前分类 找出子类, 并通过递归找出子类的子类
private static List<SysMenuDTO> getChildCategoryList(SysMenuDTO currMenu, List<SysMenuDTO> menuDTOS) {
return menuDTOS.stream().filter(o -> o.getParentId().equals(currMenu.getId()))
.peek(o -> o.setChildren(getChildCategoryList(o, menuDTOS)))
.sorted(Comparator.comparingInt(SysMenuDTO::getSort))
.collect(Collectors.toList());
}
/**
* 两层循环实现建树
*
* @param treeNodes 所有的菜单
* @param root 父节点ID
* @return 菜单树
*/
public static <T extends TreeNodeDTO> List<T> build(List<T> treeNodes, Object root) {
List<T> trees = new ArrayList<>();
for (T treeNode : treeNodes) {
if (root.equals(treeNode.getParentId())) {
trees.add(treeNode);
}
for (T it : treeNodes) {
if (it.getParentId().equals(treeNode.getId())) {
if (treeNode.getChildren() == null) {
treeNode.setChildren(new ArrayList<>());
}
treeNode.add(it);
}
}
}
return trees;
}
}
两次循环建树的基础实体类
@Data
public class TreeNodeDTO {
protected Long id;
protected Long parentId;
protected List<TreeNodeDTO> children = new ArrayList<>();
public void add(TreeNodeDTO node) {
children.add(node);
}
}
使用
TreeUtil.build(list, -1)
工具类中第一个方法所用到的实体
@Data
public class SysMenuDTO extends BaseDTO {
private Long id;
/**
* 菜单名称
*/
private String menuName;
/**
* 菜单编码
*/
private String menuCode;
/**
* 前端URL
*/
private String path;
/**
* 父菜单ID
*/
private Long parentId;
/**
* 排序值
*/
private int sort;
private List<SysMenuDTO> children;
}