Java分组返回树形数据

/**
 * @date 2023/10/25
 * @description
 */

import com.alibaba.fastjson2.JSON;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program: 工具箱
 * @description 返回树形数据
 * @date 2023/9/15
 */
public class T1 {
    static class Node {
        Integer id;
        Integer pid;
        String name;

        List<Node> treeNode = new ArrayList<>();

        public List<Node> getTreeNode() {
            return treeNode;
        }

        public void setTreeNode(List<Node> treeNode) {
            this.treeNode = treeNode;
        }

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public Integer getPid() {
            return pid;
        }

        public void setPid(Integer pid) {
            this.pid = pid;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Node(Integer id, Integer pid, String name) {
            this.id = id;
            this.pid = pid;
            this.name = name;
        }

        public Node() {
        }

        @Override
        public String toString() {
            return "Node{" +
                    "id=" + id +
                    ", pid=" + pid +
                    ", name='" + name + '\'' +
                    ", treeNode=" + treeNode +
                    '}';
        }
    }

    /**
     * 实现方式1,儿子为空不显示
     */
    public static void main1() {
        long l1 = System.currentTimeMillis();
        Node A = new Node(1, 0, "A");
        Node B = new Node(2, 1, "B");
        Node C = new Node(3, 2, "C");
        Node B1 = new Node(4, 1, "B1");

        Node C1 = new Node(5, 0, "C1");
        // 组装树状结构
        List<Node> nodes = Arrays.asList(A, B, C, B1, C1);

        //将这些非顶级节点的数据按pid进行分组,这个是根据pid为key
        //第一步过滤非pid=0的节点
        //第二步进行分组
        Map<Integer, List<Node>> nodeMap = nodes.stream().filter(node -> node.getPid() != 0).collect(Collectors.groupingBy(node -> node.getPid()));

        //循环设置对应的子节点(根据id=pid)上一步以pid为key所以就直接循环获取
        nodes.forEach(node -> node.setTreeNode(nodeMap.get(node.getId())));

        //过滤第一层是pid为零的数据,也就是没有根节点的数据
        List<Node> collect = nodes.stream().filter(node -> node.getPid() == 0).collect(Collectors.toList());
        System.out.println(JSON.toJSON(collect));
        long l2 = System.currentTimeMillis();
        long l = l2 - l1;
        System.out.println(l);
    }

    /**
     * 实现方式2,儿子为空也显示
     */
    public static void main2() {
        long l1 = System.currentTimeMillis();
        Node A = new Node(1, 0, "A");
        Node B = new Node(2, 1, "B");
        Node C = new Node(3, 2, "C");
        Node B1 = new Node(4, 1, "B1");

        Node C1 = new Node(5, 0, "C1");
        // 组装树状结构
        List<Node> nodes = Arrays.asList(A, B, C, B1, C1);

        //将这些非顶级节点的数据按pid进行分组,这个是根据pid为key
        //第一步构造最外层节点,即id=0的节点
        List<Node> collect = nodes.stream()
                .filter(node -> node.getPid() == 0)
                .peek(node -> {
                    node.setTreeNode(getChildren(node, nodes));//id=0的节点就为他设置孩子节点
                }).
                collect(Collectors.toList());
        System.out.println(JSON.toJSON(collect));
        long l2 = System.currentTimeMillis();
        long l = l2 - l1;
        System.out.println(l);
    }

    static List<Node> getChildren(Node node, List<Node> nodes) {
        return nodes.stream()
                .filter(item -> item.getPid().equals(node.getId()))//判断当前节点的父id是不是要设置节点的id
                .peek(item -> {
                    item.setTreeNode(getChildren(item, nodes));//如果是 为其设置孩子节点 通过递归 为每个除了最外层节点的节点设置孩子节点
                })
                .collect(Collectors.toList());
    }

    public static void main(String[] args) {
        main1();
        main2();
    }
}

结果
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值