使用stream流构造树形结构

本文介绍了如何在大数据量场景下,利用Java的Stream流高效构建树形结构。首先通过filter方法筛选出顶层节点,然后递归遍历所有节点,通过setSubList方法设置子节点列表,实现树状结构的构建。这种方法在处理大量数据时能显著提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

日常使用for循环构造树形结构,但是在遇到数据量较大的时候,使用stream流可以提高效率。所以在此展示如何使用stream流构造树形结构。

一、第一步先找出顶层节点(顶层节点的特点就是他的父节点为空,根据此条件先筛选出顶层节点。)

List<ExportOrganization> parentList = tempList.stream()
                .filter(e -> StringUtils.isBlank(e.getPcompId())
                        || "".equals(e.getPcompId()))
                .collect(Collectors.toList());

二、第二步依次遍历全部节点构造树形结构(其中的重点是
if (!subList.isEmpty()) {
getSubList(subList, all);
}
当子节点不为空,需要递归遍历子节点再次去构造树形结构

private static void getSubList(final List<ExportOrganization> parentList, final List<ExportOrganization> all) {
        for (ExportOrganization exportOrganization : parentList) {
            List<ExportOrganization> subList = all.stream().filter(o -> o.getPcompId()
                    .equals(exportOrganization.getCompId())).collect(Collectors.toList());
            exportOrganization.setSubList(subList);
            if (!subList.isEmpty()) {
                getSubList(subList, all);
            }
        }
    }
### Java 中实现树形结构类的示例 在 Java 中,树形结构可以通过自定义类来实现。以下是基于提供的引用内容以及专业知识所总结的内容。 #### 1. 定义节点类 是由节点组成的,因此首先需要定义一个 `TreeNode` 类作为基础节点类。该类应包含以下字段: - **id**: 唯一标识符。 - **parentId**: 父节点的唯一标识符。 - **children**: 当前节点的子节点列表。 ```java import java.util.ArrayList; import java.util.List; public class TreeNode { private Long id; // 节点ID private Long parentId; // 父节点ID private List<TreeNode> children = new ArrayList<>(); // 子节点集合 public TreeNode(Long id, Long parentId) { this.id = id; this.parentId = parentId; } // Getter and Setter methods public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getParentId() { return parentId; } public void setParentId(Long parentId) { this.parentId = parentId; } public List<TreeNode> getChildren() { return children; } public void addChild(TreeNode childNode) { this.children.add(childNode); } } ``` 此部分描述了如何设计基本的节点类[^1]。 --- #### 2. 扩展功能的具体实例 如果需要更复杂的属性(如权限名称、路径等),可以根据需求扩展上述类。例如,在引用中提到的 `PermissionTree` 可以作为一个具体的例子[^4]。 ```java import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.ObjectIdGenerators; @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") @Data @EqualsAndHashCode(callSuper = true) public class PermissionTree extends TreeNode { private String permissionName; // 权限名称 private String permissionCode; // 权限编码 private String path; // 访问路径 private Integer sort; // 排序号 private String label; // 显示标签 private boolean hasChildren; // 是否有子节点 public PermissionTree(Long id, Long parentId, String permissionName, String permissionCode, String path, Integer sort, String label, boolean hasChildren) { super(id, parentId); // 调用父类构造函数 this.permissionName = permissionName; this.permissionCode = permissionCode; this.path = path; this.sort = sort; this.label = label; this.hasChildren = hasChildren; } } ``` 此处展示了如何继承通用的 `TreeNode` 并增加特定领域所需的额外属性。 --- #### 3. 构建树形结构的方法 为了从扁平化的数据源(如数据库表)构建树形结构,可以编写一个工具方法 `makeTree()`。这种方法通常用于处理关系型数据库中的形数据[^2]。 ```java import java.util.*; import java.util.stream.Collectors; public class TreeUtils { /** * 将扁平化数据转换为树形结构 * * @param nodes 扁平化数据集 * @return 根节点列表 */ public static List<PermissionTree> makeTree(List<PermissionTree> nodes) { Map<Long, PermissionTree> nodeMap = new HashMap<>(); // 创建哈希映射以便快速查找 for (PermissionTree node : nodes) { nodeMap.put(node.getId(), node); } List<PermissionTree> rootNodes = new ArrayList<>(); // 遍历所有节点,找到其父节点并挂载到对应的子节点上 for (PermissionTree node : nodes) { if (node.getParentId() != null && nodeMap.containsKey(node.getParentId())) { PermissionTree parentNode = nodeMap.get(node.getParentId()); parentNode.addChild(node); } else { rootNodes.add(node); } } return rootNodes; } } ``` 这段代码实现了将一组带有父子关系的对象转化为完整的树形结构的功能。 --- #### 4. 使用示例 假设有一个简单的权限管理系统的数据如下所示: | ID | Parent_ID | Name | |----|-----------|------------| | 1 | NULL | Root Menu | | 2 | 1 | Submenu A | | 3 | 1 | Submenu B | 可以按照以下方式调用 `makeTree()` 方法: ```java List<PermissionTree> flatData = Arrays.asList( new PermissionTree(1L, null, "Root Menu", "", "/", 0, "Root", false), new PermissionTree(2L, 1L, "Submenu A", "", "/a", 1, "A", false), new PermissionTree(3L, 1L, "Submenu B", "", "/b", 2, "B", false) ); List<PermissionTree> treeStructure = TreeUtils.makeTree(flatData); System.out.println(treeStructure.toString()); // 输出树形结构 ``` 这一步骤说明了如何使用工具类完成树形结构的实际操作[^3]。 --- ### 总结 以上介绍了如何通过自定义类和工具方法在 Java 中实现树形结构的设计与构建过程。这种技术广泛应用于实际项目开发中,尤其是在涉及分层显示的需求场景下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值