Java 8 中使用 Stream 遍历树形结构

news2024/12/24 11:37:11

        在实际开发中,我们经常会开发菜单,树形结构,数据库一般就使用父id来表示,为了降低数据库的查询压力,我们可以使用Java8中的Stream流一次性把数据查出来,然后通过流式处理,我们一起来看看,代码实现为了实现简单,就模拟查看数据库所有数据到List里面。

        为了实现这种效果:

下面就使用的一个简单的例子进行演示:

实体类:Departments.java

@Data
@Builder
public class Departments {
    /**
     * id
     */
    public Integer id;
    /**
     * 名称
     */
    public String name;
    /**
     * 父id ,根节点为0
     */
    public Integer parentId;
    /**
     * 子节点信息
     */
    public List<Departments> childList;


    public Departments(Integer id, String name, Integer parentId) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
    }

    public Departments(Integer id, String name, Integer parentId, List<Departments> childList) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
        this.childList = childList;
    }
}

使用递归构建树形结构

public class DepartmentsTreeTest {

    @Test
    public void testtree() {
        // 模拟从数据库查询出来的菜单数据
        List<Departments> departments = Arrays.asList(
                new Departments(1, "总行", 0),
                new Departments(2, "分行", 1),
                new Departments(3, "攀枝花分行", 2),
                new Departments(4, "成都分行", 2),
                new Departments(5, "凉山分行", 2),
                new Departments(6, "支行", 1),
                new Departments(7, "绵阳支行", 6),
                new Departments(8, "德阳支行", 6),
                new Departments(9, "绵阳支行街道", 7),
                new Departments(10, "德阳支行街道", 7),
                new Departments(11, "子公司", 1),
                new Departments(12, "我是子公司", 11)
        );
        // 获取部门菜单信息
        // 通过filter()方法筛选出所有部门菜单项。部门的特征是parentId为0,即没有父节点。这些部门菜单项的列表被称为collect
        List<Departments> collect = departments.stream().filter(m -> m.getParentId() == 0)
                // 对于每个部门菜单项,我们使用map()方法来递归所有部门地获取其所有子菜单项,并将这些子菜单项设置为部门菜单项的childList属性。
                .map((m) -> {
                    m.setChildList(getChildrens(m, departments));
                    return m;
                }
        ).collect(Collectors.toList());
        System.out.println("-------转json输出结果-------");
        System.out.println(JSON.toJSON(collect));
    }

    /**
     * 递归查询部门
     * @param root 部门
     * @param all  所有节点
     * @return 包含所有部门的列表
     */
    private List<Departments> getChildrens(Departments root, List<Departments> all) {
        // 过滤出所有与部门的id相匹配的部门
        List<Departments> children = all.stream().filter(m -> {
            // 当所有节点中的parentid与部门的id一致时,表示为部门的部门
            return Objects.equals(m.getParentId(), root.getId());
        }).map(
                (m) -> {
                    // 递归查询该部门的部门
                    m.setChildList(getChildrens(m, all));
                    return m;
                }
        ).collect(Collectors.toList());
        return children;
    }

}

输出结果:

        输出的JSON格式的结果你可以直接复制进行测试查看。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/836668.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用openTCS实现车辆调度系统(二)openTCS下载部署

openTCS下载 **openTCS不是一个部署即用的系统&#xff0c;需要自己做一部分二次开发工作。这里先下载打包好的应用&#xff0c;了解openTCS的功能&#xff1a;应用下载地址**整个部署使用部分包括&#xff0c;启动程序、应用地图、准备设备、下发订单。 1、启动调度内核 双…

idea中cherry pick怎么用

网上的文章比较杂乱&#xff0c;具体idea里面怎么操作&#xff0c;好像没有个成型的文章 cherry pick的作用&#xff1a; 简而言之就是同一个commit&#xff0c;然后复制提交到其他分支&#xff08;只检出本次提交的&#xff09;&#xff1b; 解决的问题&#xff1a; 两个分…

轻松搭建酒店小程序

酒店小程序的制作并不需要编程经验&#xff0c;只需要按照以下步骤进行操作&#xff0c;就能很快地搭建自己的小程序商城。 第一步&#xff0c;注册登录账号进入操作后台&#xff0c;找到并点击【商城】中的【去管理】进入商城的后台管理页面&#xff0c;然后再点击【小程序商城…

原型模式与享元模式:提升系统性能的利器

原型模式和享元模式&#xff0c;前者是在创建多个实例时&#xff0c;对创建过程的性能进行调优&#xff1b;后者是用减 少创建实例的方式&#xff0c;来调优系统性能。这么看&#xff0c;你会不会觉得两个模式有点相互矛盾呢&#xff1f; 在有些场景下&#xff0c;我们需要重复…

Linux安装cuda和cudnn教程

Linux安装cuda和cudnn教程 文章目录 1.下载cuda和cudnn2. 安装cuda并检验安装是否成功3. 安装cudnn4.验证cuda是否能用代码附件&#xff1a;解压各种格式文件的Linux命令参考文献 卸载之前的cuda 卸载之前的cuda教程 1.下载cuda和cudnn CUDA下载地址&#xff1a;https://dev…

Tailwind CSS:简洁高效的工具,提升前端开发体验

112. Tailwind CSS&#xff1a;简洁高效的工具&#xff0c;提升前端开发体验 1. 什么是Tailwind CSS&#xff1f; Tailwind CSS是由Adam Wathan、Jonathan Reinink、David Hemphill和Steve Schoger等人共同创建的一种现代CSS框架。与传统的CSS框架不同&#xff0c;Tailwind CS…

如何用 NPS 确定研发优先级,打破技术与业务的次元壁?

「不了解利益相关者的需求是僵尸 Scrum 团队的四大常见症状之一&#xff0c;其主要表现为成员们忽视价值链上下游的内容&#xff0c;无法或不愿意带来任何改变或影响」&#xff0c;《拯救僵尸 Scrum》如是写道。 它们的工作&#xff0c;以及工作所涉及的组织&#xff0c;往往被…

Spark、RDD、Hive 、Hadoop-Hive 和传统关系型数据库区别

Hive Hadoop Hive 和传统关系型数据库区别 Spark 概念 基于内存的分布式计算框架 只负责算 不负责存 spark 在离线计算 功能上 类似于mapreduce的作用 MapReduce的缺点 运行速度慢 &#xff08;没有充分利用内存&#xff09;接口比较简单&#xff0c;仅支持Map Reduce功能…

AI写作宝有哪些,分享两种AI写作工具

AI写作宝是一种基于人工智能技术的写作辅助工具。它可以根据用户输入的关键词和主题快速生成文章。AI写作宝可以为用户节省大量的时间和精力&#xff0c;帮助用户快速生成高质量的文章。今天就为大家推荐两款AI写作宝&#xff1a; 一、AI创作家 AI创作家是一款基于人工智能技…

在java中存储对象到redis出现类型转换异常的解决方法

**出现的问题,**此时的redisCatch已经注入 原因:这里传进来的是一个对象,redis不能直接将对象存到String中,必须将对象进行序列化转成json字符串再存储,其次.传进来的对象不能是null 再重新启动就行了

整会promise这8个高级用法,再被问倒来喷我

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 发现很多人还只会promise常规用法 在js项目中&#xff0c;promise的使用应该是必不可少的&#xff0c;但我发现在同事和面试者中&#xff0c;很多中级或…

GD32F103VE睡眠与唤醒

GD32F103VE睡眠与唤醒&#xff0c;兆易官网给的程序没有测试。等测试后&#xff0c;才发现有问题。 现修改&#xff0c;测试如下&#xff1a; #include "SleepMode.h" #include "delay.h"u8 WFE_CMD_EnterSleepModeFlag;void Enter_DeepSleepMode(void);…

关于计算机大学生秋招面试的那点事?(Golang篇)

前言&#xff1b; Go语言&#xff08;简称Golang&#xff09;越来越受到开发者的关注和欢迎。它由Google公司于2009年推出&#xff0c;旨在提供更好的性能和并发性能。眼下&#xff0c;越来越多的公司在使用它&#xff0c;比如著名的云计算服务商AWS&#xff0c;以及知名电商京…

【2023.8】docker一键部署wvp-GB28181-pro和ZLMediaKit过程全记录

安装docker 使用的操作系统是ubuntu20.04 如何在 Ubuntu 20.04 上安装和使用 Docker https://developer.aliyun.com/article/762674 docker拉取配置好的ZLMediaKIt和wvp-GB28181-pro docker pull 648540858/wvp_pro第一次运行 docker一键运行ZLMediaKIt和wvp-GB28181-pro …

Springboot集成支付宝微信支付项目

找了一个支付宝微信小项目&#xff0c;有兴趣有的大家可以学习一下 后端&#xff1a;shiringbootmybatis-plusswagger2alipaywxpay 前端VUE 先看首页 目前微信支付还没有对接&#xff0c;但是方法和配置文件已经有了&#xff0c;只需按照自己配置就可以了。 点击在支付宝支付 输…

Cpp学习——string(1)

目录 ​编辑 一&#xff0c;string简介 二&#xff0c;string的使用 1.string对象的构造方式 2.string的遍历 1.for普通遍历 2.迭代器的方式遍历 3.string中的函数 一&#xff0c;string简介 要学习string就要先知道string是个啥。string是个啥呢&#xff1f;string其实…

RISC-V基础之函数调用(五)函数递归调用及函数参数数量溢出(超出现有寄存器个数)约定(包含实例)

首先先解释一下栈在函数调用中的作用&#xff0c;更详细的部分请参照考研复习之数据结构笔记&#xff08;五&#xff09;栈和队列&#xff08;上&#xff09;&#xff08;包含栈的相关内容&#xff09;_管二狗赶快去工作&#xff01;的博客-CSDN博客 函数嵌套调用栈的作用是用…

移动应用开发:为移动设备优化的在线教育培训平台

移动应用开发在当今数字化时代扮演着至关重要的角色&#xff0c;尤其是在在线教育培训领域。移动设备的普及和使用&#xff0c;使得人们可以随时随地访问学习资源&#xff0c;这为在线教育培训平台提供了巨大的发展机会。本文将探讨如何为移动设备优化在线教育培训平台&#xf…

常见的数据结构(顺序表、顺序表、链表、栈、队列、二叉树)

线性表&#xff08;Linear List&#xff09;  1.什么是线性表 2.线性表的特点 3.线性表的基本运算 顺序表 1.什么是顺序表 2.时间复杂度&#xff1a; 链表 1.什么是链表 2.单向链表 3. 双向链表 4.ArrayList和LinkedList的使用 栈Stack  1.什么是栈  2.栈的基本方法 队列…

新人如何高效写 API 文档

什么是 API 文档&#xff1f; 在深入研究 API 文档之前&#xff0c;让我简要解释一下 API 是什么以及它的基本功能。 API 是应用程序编程接口的首字母缩写。 ​ 编辑 切换为居中 通过 API 将设备连接到数据库 无论你是初学者还是高级开发人员&#xff0c;你都会在软件开发…