利用map遍历

最简单,时间空间复杂度最低

// 获取出所有的父节点ID(用于数据返回的根节点)
List<String> parentIdList = treeDtos.stream().filter(k -> "root".equals(k.getPid()))
        .map(SysTreeOrgDto::getId)
        .collect(Collectors.toList());
// key:Id,value:对象
Map<String, SysTreeOrgDto> sysTreeOrgMap = treeDtos.stream().collect(Collectors.toMap(SysTreeOrgDto::getId, Function.identity(), (v1, v2) -> v1));
// 一次循环,将源数据所有的子节点数据,放到父节点的Children对象中
treeDtos.forEach(org->{
    SysTreeOrgDto sysTreeOrgDto = sysTreeOrgMap.get(org.getOrgCode());
    if (sysTreeOrgDto != null){
        if (org.getChildren() == null){
            org.setChildren(new ArrayList());
            org.getChildren().add(org);
        }
        org.getChildren().add(org);
    }
});
// 取出父节点对应的树形结构
List<SysTreeOrgDto> result = new ArrayList<>();
for (String parentId : parentIdList) {
    SysTreeOrgDto sysTreeOrgDto = sysTreeOrgMap.get(parentId);
    result.add(sysTreeOrgDto);
}

递归循环

class MenuItem {
    int id;
    String name;
    int parentId;
    List<MenuItem> subItems;
}

/**
 * 
 * @param items 源数据列表
 * @return
 */
public static MenuItem buildTree(List<MenuItem> items) {
    MenuItem root = null;
    for (MenuItem item : items) {
        if (item.parentId == -1) { // 假设-1为根节点的parentId
            root = item;
            break;
        }
    }
    addSubItems(items, root);
    return root;
}

/**
 * 
 * @param items 源数据列表
 * @param parent 父节点
 */
private static void addSubItems(List<MenuItem> items, MenuItem parent) {
    for (MenuItem item : items) {
        if (item.parentId == parent.id) {
            parent.subItems.add(item);
            addSubItems(items, item); // 递归添加子项
        }
    }
}

public static void main(String[] args) {
    List<MenuItem> menuItems = new ArrayList<>();
    // 假设菜单项数据
    menuItems.add(new MenuItem(1, "Item 1", -1));
    menuItems.add(new MenuItem(2, "Item 2", 1));
    menuItems.add(new MenuItem(3, "Item 3", 1));
    menuItems.add(new MenuItem(4, "Item 4", 2));
    menuItems.add(new MenuItem(5, "Item 5", -1));

    MenuItem menuTree = buildTree(menuItems);
    // 打印构建好的树形结构
    printTree(menuTree, 0);
}

/**
 * 生成序号
 * @param item 树结构数据
 * @param level 序号
 */
private static void printTree(MenuItem item, int level) {
    StringBuilder prefix = new StringBuilder();
    for (int i = 0; i < level; i++) {
        prefix.append("--");
    }
    System.out.println(prefix.toString() + item.name);
    for (MenuItem subItem : item.subItems) {
        printTree(subItem, level + 1);
    }
}

Stream流处理

public static void main(String[] args) {
    // 获取源数据列表
    List<Department> departments = departmentMapper.listAllByTenantManual();
    // 获取父节点对象
    Department department = departmentMapper.selectOne("root");
    // 生成树结构
    List<Department> allSubCategories = this.getChildrens(department.getId(), departments);
    // 树结构数据放入父节点对象中
    department.setSubLists(allSubCategories);
    // 将树形结构转为平形结构
    List<Department> children = new ArrayList<>();
    getAllChildNodesRecursive(department, children);
}

/**
 * 递归查询子父类
 *
 * @param id  当前节点的父id
 * @param all 所有部门信息
 * @return
 */
private List<Department> getChildrens(Long id, List<Department> all) {
    return all.stream()
            .filter(categoryVo -> categoryVo.getParentId() != null && categoryVo.getParentId().equals(id))
            .peek(categoryVo -> {
                // 子菜单可能还有子菜单, 因此递归查询 , 查询出子菜单
                categoryVo.setSubLists(getChildrens(categoryVo.getId(), all));
            }).collect(Collectors.toList());
}

/**
 * 树形结构转为平形结构
 * @param node 树结构(subLists)
 * @param result
 */
private static void getAllChildNodesRecursive(Department node, List<Department> result) {
    if (node == null) {
        return;
    }
    // 添加当前节点的数据
    result.add(node);
    for (Department child : node.getSubLists()) {
        // 递归获取子节点的子节点
        getAllChildNodesRecursive(child, result);
    }
}

Q.E.D.


如人饮水、冷暖自知