Java列表转树形结构的工具

不废话,直接上代码

一、工具函数

可以直接使用list2tree()实现列表转树形结构

package com.server.utils.tree;import org.springframework.beans.BeanUtils;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;/*** @author visy.wang* @date 2024/6/27 21:27*/
public class TreeUtil {public static <T,K,R> R list2tree(List<T> list,K rootPid,Function<T,K> idGetter,Function<T,K> pidGetter,Function<T,R> nodeGetter,String childrenName,Supplier<R> nodeSupplier,BiConsumer<R,R> childAdder){Map<K, R> map = new HashMap<>();for (T t : list) {K id = idGetter.apply(t), pid = pidGetter.apply(t);//查找当前节点R node = map.get(id);if(node == null){//当前节点不存在则创建node = nodeGetter.apply(t);map.put(id, node);}else{//当前节点已存在(被其他节点以父节点加入),补全剩余字段BeanUtils.copyProperties(nodeGetter.apply(t), node, childrenName);}//查找父节点R parent = map.get(pid);if(parent == null){//父节点不存在,则创建父节点,并将自身添加到父节点的子节点集合中parent = nodeSupplier.get();childAdder.accept(parent, node);map.put(pid, parent);}else{//父节点已存在,直接将自身添加到父节点的子节点集合中childAdder.accept(parent, node);}}return map.get(rootPid);}
}
二、原始对象
package com.server.utils.tree;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;/*** 菜单*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Menu implements Serializable {private static final long serialVersionUID = 1L;/*** 菜单id*/private Long id;/*** 父id*/private Long fid;/*** 机构名称*/private String name;/*** 模块id*/private Integer level;/*** 状态   1 启用 2 停用*/private Integer status;/*** 权重*/private Integer weight;
}
三、节点对象
package com.server.utils.tree;import lombok.Data;
import lombok.EqualsAndHashCode;import java.util.ArrayList;
import java.util.List;/*** @author visy.wang* @date 2024/6/27 21:54*/
@Data
@EqualsAndHashCode(callSuper = true)
public class MenuNode extends Menu {/*** 是否勾选*/private Integer isCheck;/*** 子菜单列表*/private List<MenuNode> children;public void addChild(MenuNode child){if(children == null){children = new ArrayList<>();}children.add(child);}
}
四、测试
package com.server.utils.tree;import com.alibaba.fastjson.JSON;
import org.springframework.beans.BeanUtils;import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;/*** @author visy.wang* @date 2024/6/27 21:55*/
public class Test {public static void main(String[] args) {List<Menu> menuList = new ArrayList<>();//顺序可以任意调整,不影响结果menuList.add(new Menu(1L, null, "菜单A", 1, 1,1));menuList.add(new Menu(4L, 2L, "菜单BA", 2, 1,4));menuList.add(new Menu(3L, 1L, "菜单AA", 2, 1,3));menuList.add(new Menu(5L, 3L, "菜单AAA", 3, 1,5));menuList.add(new Menu(2L, null, "菜单B", 1, 1,2));//勾选的菜单ID集合Set<Long> checkedMenuIds = new HashSet<>();checkedMenuIds.add(3L);checkedMenuIds.add(5L);MenuNode root = TreeUtil.list2tree(menuList, //原始列表null, //根节点ID,用于提取顶层节点Menu::getId, //获取ID的方法,也可以指定别的字段Menu::getFid, //获取父ID的方法,也可以指定别的字段,但是必须和上面的方法对应menu -> { //将列表表中的原始对象转换成节点对象(一般来说比原始对象多了对子节点集合的持有,除此之外也可以按需要增减字段)MenuNode node = new MenuNode();//创建一个节点BeanUtils.copyProperties(menu, node);//复制原始对象的字段到节点对象node.setIsCheck(checkedMenuIds.contains(menu.getId()) ? 1 : 0);//单独设置其他字段return node;//返回节点对象},"children", //子节点集合字段名MenuNode::new, //节点对象的构造方法,用于创建一个新的父节点对象MenuNode::addChild //指定添加子节点的方法);System.out.println(JSON.toJSONString(root.getChildren()));}
}
五、打印结果
[{"children": [{"children": [{"fid": 3, "id": 5, "isCheck": 1, "level": 3, "name": "菜单AAA", "status": 1, "weight": 5}], "fid": 1, "id": 3, "isCheck": 1, "level": 2, "name": "菜单AA", "status": 1, "weight": 3}], "id": 1, "isCheck": 0, "level": 1, "name": "菜单A", "status": 1, "weight": 1}, {"children": [{"fid": 2, "id": 4, "isCheck": 0, "level": 2, "name": "菜单BA", "status": 1, "weight": 4}], "id": 2, "isCheck": 0, "level": 1, "name": "菜单B", "status": 1, "weight": 2}
]

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

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

相关文章

从源码到上线:直播带货系统与短视频商城APP开发全流程

很多人问小编&#xff0c;一个完整的直播带货系统和短视频商城APP是如何从源码开发到最终上线的呢&#xff1f;今天&#xff0c;笔者将详细介绍这一全过程。 一、需求分析与规划 1.市场调研与需求分析&#xff1a;首先需要进行市场调研&#xff0c;了解当前市场的需求和竞争情…

入职必备-Git 2种方式拉取代码

【SSH方式】: 1.复制电子邮箱 2.git bash 打开窗口 ssh-keygen -t rsa -C liuchangprimecare.group 3.一路回车&#xff0c;然后查看C:\Users\LiuChang.ssh里面的文件 打开id_rsa.pub文件&#xff0c;复制代码 4.添加到GitLab的公钥输入框 5.然后 git clone gitgitlab.pr…

使用容器配置文件构建任意应用镜像_并将应用镜像推送到公共仓库共享_应用分享与启动---分布式云原生部署架构搭建012

上面我们编写好了应用,并且,安装好了redis 现在我们把应用打包成镜像. 以前是这样做的,不方便,因为需要在服务器上,安装jdk什么的,现在有了 镜像就不用,给服务器安装镜像什么的了 以后所有机器都安装docker以后,就直接运行就可以了 首先看一下,安装java应用,需要 用到openjd…

指纹浏览器是什么?跨境多账号安全如何保证?

随着电子商务的蓬勃发展&#xff0c;越来越多的商家选择开设多店来扩大经营规模。然而多店运营也带来了一系列的挑战&#xff0c;其中之一就是账号安全。 1. 了解反检测浏览器和代理服务器 在我们开始讨论如何有效地使用反检测浏览器之前&#xff0c;我们首先需要了解这两个工…

openlayer 我的标注功能

背景&#xff1a; 通过openlayer库&#xff0c;可以在地图上实现绘制点、线、面。 并把绘制的结果添加到我的标注的弹框。 我的标注功能&#xff0c;包括&#xff1a;我的标注查询结果的数据展示&#xff1b;添加分组&#xff1b;添加我的标注&#xff1b;编辑分组、删除分组&a…

经典神经网络(13)GPT-1、GPT-2原理及nanoGPT源码分析(GPT-2)

经典神经网络(13)GPT-1、GPT-2原理及nanoGPT源码分析(GPT-2) 2022 年 11 月&#xff0c;ChatGPT 成功面世&#xff0c;成为历史上用户增长最快的消费者应用。与 Google、FaceBook等公司不同&#xff0c;OpenAI 从初代模型 GPT-1 开始&#xff0c;始终贯彻只有解码器&#xff0…

【机器学习300问】134、什么是主成分分析(PCA)?

假设你的房间堆满了各种各样的物品&#xff0c;书籍、衣服、玩具等等&#xff0c;它们杂乱无章地散落各处。现在&#xff0c;你想要清理房间&#xff0c;但又不想扔掉任何东西&#xff0c;只是希望让房间看起来更整洁&#xff0c;更容易管理。 你开始思考&#xff0c;能否将物品…

深入解读 ThreadLocal 源码及其在 ThreadLocalContext 中的使用

深入解读 ThreadLocal 源码及其在 ThreadLocalContext 中的使用 ThreadLocal 是 Java 中用于提供线程局部变量的一种机制&#xff0c;通过为每个线程提供独立的变量副本&#xff0c;保证了线程之间的数据隔离性。本文将深入解读 ThreadLocal 的源码&#xff0c;并展示其在 Thr…

以数治税时代来临,企业如何应对?

全电发票是数字经济时代发票的新形态&#xff0c;顺应了数字经济潮流。现如今&#xff0c;国家正全力推动行业数字化进程&#xff0c;预计&#xff0c;2025年将基本实现发票全领域、全环节、全要素电子化&#xff0c;实现税务执法、服务、监管与大数据智能化应用深度融合、高效…

Spring事务的源码底层实现

文章目录 事务理论执行过程EnableTransactionManagement底层实现 事务 在线流程图 理论执行过程 通过事务管理器创建一个连接对象connection1设置事务隔离级别、是否只读等conn1.autocommit(false)将conn1存入ThreadLocal中Map<DataSource,Connection>执行目标方法、多…

Session会话与请求域的区别

session会话和请求域&#xff08;也称为request域&#xff09;都是用于存储和管理用户特定信息的重要概念&#xff0c;但它们在作用范围和生命周期上有显著的不同。 请求域 (Request Domain) 作用范围&#xff1a;请求域是面向单次请求的。每次HTTP请求都会创建一个新的request…

Java中的程序异常处理介绍

一、异常处理机制 Java提供了更加优秀的解决办法&#xff1a;异常处理机制。 异常处理机制能让程序在异常发生时&#xff0c;按照代码的预先设定的异常处理逻辑&#xff0c;针对性地处理异常&#xff0c;让程序尽最大可能恢复正常并继续执行&#xff0c;且保持代码的清晰。 Ja…

算法刷题日志 —— 数组和位运算

文章目录 [461. 汉明距离](https://leetcode.cn/problems/hamming-distance/submissions/542447020/)[448. 找到所有数组中消失的数字](https://leetcode.cn/problems/find-all-numbers-disappeared-in-an-array/submissions/)[136. 只出现一次的数字](https://leetcode.cn/pro…

最长回文串

描述&#xff1a; 最长回文串 思路&#xff1a; 统计每个字母出现次数&#xff0c;如果是偶数&#xff0c;ret x;如果是存在奇数的话&#xff0c;就可以放在中间&#xff0c;ret 1. 代码&#xff1a; class Solution { public:int hash[200];int longestPalindrome(str…

记一次rocketMq根据配置文件读取listener consumerGroup异常

记一次rocketMq根据配置文件读取listener consumerGroup异常 引现象处理 引 rocketMq通常需要配置topic和consumerGroup&#xff0c;而这两个参数往往是不会直接定值写死&#xff0c;而是通过application配置文件配置变量的方式来注入。 现象 今天新增了几个topic和consumer…

AI智能修复视频,垃圾画质也变高清 HD——牛小影

很多时候&#xff0c;从网上下载的视频或监控视频都是模糊的。有什么方法或者软件可以让哪些模糊的视频恢复清晰吗&#xff1f;今天就给大家推荐一个可以使模糊的视频变清晰的软件。 我们都知道用PS或者一些修复工具可以修复模糊的图片&#xff0c;但是很多人不知道的是视频也可…

构建LangChain应用程序的示例代码:46、使用 Meta-Prompt 构建自我改进代理的 LangChain 实现

Meta-Prompt 实现 摘要&#xff1a; 本文介绍了 Noah Goodman 提出的 Meta-Prompt 方法的 LangChain 实现&#xff0c;该方法用于构建能够自我反思和改进的智能代理。 核心思想&#xff1a; Meta-Prompt 的核心思想是促使代理反思自己的性能&#xff0c;并修改自己的指令。…

上班族要怎么挑选智能猫砂盆?今年最受欢迎的牌子都在这里了!

对于上班族来说&#xff0c;猫砂盆里的猫屎到底该如何是好&#xff0c;放到下班回来再铲&#xff0c;猫砂的臭味早就飘满屋子&#xff0c;想立刻铲掉吧&#xff0c;班不要上啦&#xff1f;可是不铲就会生细菌&#xff0c;谁也不想花个几千块去给猫咪看病吧&#xff0c;谁不希望…

运算逻辑符的短路特性

在开发时遇到了这样一个问题&#xff1a; public boolean isPasswordNullOrEmpty(Context context) {return getPassword(context) ! null && !getPassword(context).isEmpty; } 这个方法想要实现的效果是获取一个password是否为空的状态&#xff0c;但会出现报错&am…

Linux:进程和计划任务管理

目录 一、程序和进程 1.1、程序 1.2、进程 1.3、线程 1.4、协程 二、查看进程相关命令 2.1、ps命令&#xff08;查看静态的进程统计信息&#xff09; 第一行为列表标题&#xff0c;其中各字段的含义描述如下 2.2、top命令&#xff08;查看进程动态信息&#xff09; 2…