简单封装一个类似菜单栏的树状结构转换

2024-08-21 14:36

本文主要是介绍简单封装一个类似菜单栏的树状结构转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

充血的菜单实体类

@Data
public class Menu {public Integer id;public String name;public Integer parentId;// 根节点为0public List<Menu> childList;public Menu(Integer id, String name, Integer parentId) {this.id = id;this.name = name;this.parentId = parentId;this.childList = new ArrayList<>();}public static List<Menu> selectAll() {return Arrays.asList(new Menu(1, "根节点", 0),new Menu(2, "子节点1", 1),new Menu(3, "子节点1.1", 2),new Menu(4, "子节点1.2", 2),new Menu(5, "根节点1.3", 2),new Menu(6, "根节点2", 1),new Menu(7, "根节点2.1", 6),new Menu(8, "根节点2.2", 6),new Menu(9, "根节点2.2.1", 7),new Menu(10, "根节点2.2.2", 7),new Menu(11, "根节点3", 1),new Menu(12, "根节点3.1", 11));}
}

先做实现

public class Test {public static void main(String[] args) {List<Menu> menuList = Menu.selectAll();// 1:遍历(O(n))节点并查找(O(1))加入父节点。总复杂度为O(n)。Map<Integer, Menu> menuMap = menuList.stream().collect(Collectors.toMap(Menu::getId, menu -> menu));menuMap.forEach((key, value) -> {if (value.getParentId() == 0) return; // 根节点不处理menuMap.get(value.getParentId()).getChildList().add(value);});Menu root = menuMap.get(1);System.out.println(root);}
}

封装一下,主要抽象了实体类的ID、父节点ID、子节点列表这三个字段的Getter

public class Test {public static void main(String[] args) {List<Menu> menuList = Menu.selectAll();// 抽象class Tree<T>{public T parse(List<T> list, Function<T, Integer> getId, Function<T,Integer> getParentId, Function<T, Collection<T>> getChildList) {Map<Integer, T> map = list.stream().collect(Collectors.toMap(getId, t -> t));map.forEach((key, value) -> {if (getParentId.apply(value) == 0) return; // 根节点不处理getChildList.apply(map.get(getParentId.apply(value))).add(value);});return map.get(1);}}Menu root = new Tree<Menu>().parse(menuList, Menu::getId, Menu::getParentId, Menu::getChildList);System.out.println(root);}
}

再封装一下,把根节点的判断条件封装了

public class Test {public static void main(String[] args) {List<Menu> menuList = Menu.selectAll();// 抽象class Tree<T>{public T parse(List<T> list, Function<T, Integer> getId, Function<T,Integer> getParentId, Function<T, Collection<T>> getChildList,Function<T,Boolean> isRoot) {AtomicReference<T> root = new AtomicReference<>();Map<Integer, T> map = list.stream().collect(Collectors.toMap(getId, t -> t));map.forEach((key, value) -> {if (isRoot.apply(value)) {root.set(value);return; // 根节点不处理}getChildList.apply(map.get(getParentId.apply(value))).add(value);});return root.get();}}Menu root = new Tree<Menu>().parse(menuList, Menu::getId, Menu::getParentId, Menu::getChildList, menu -> menu.getParentId() == 0);System.out.println(root);}
}

再再封装,类泛型有点大,改为方法泛型吧

public class Test {public static void main(String[] args) {List<Menu> menuList = Menu.selectAll();// 抽象class Tree {public static <T> T parse(List<T> list, Function<T, Integer> getId, Function<T,Integer> getParentId, Function<T, Collection<T>> getChildList,Function<T,Boolean> isRoot) {AtomicReference<T> root = new AtomicReference<>();Map<Integer, T> map = list.stream().collect(Collectors.toMap(getId, t -> t));map.forEach((key, value) -> {if (isRoot.apply(value)) {root.set(value);return; // 根节点不处理}getChildList.apply(map.get(getParentId.apply(value))).add(value);});return root.get();}}Menu root = Tree.parse(menuList, Menu::getId, Menu::getParentId, Menu::getChildList, menu -> menu.getParentId() == 0);System.out.println(root);}
}

这篇关于简单封装一个类似菜单栏的树状结构转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1093439

相关文章

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Vite 打包目录结构自定义配置小结

《Vite打包目录结构自定义配置小结》在Vite工程开发中,默认打包后的dist目录资源常集中在asset目录下,不利于资源管理,本文基于Rollup配置原理,本文就来介绍一下通过Vite配置自定义... 目录一、实现原理二、具体配置步骤1. 基础配置文件2. 配置说明(1)js 资源分离(2)非 JS 资

Python中Json和其他类型相互转换的实现示例

《Python中Json和其他类型相互转换的实现示例》本文介绍了在Python中使用json模块实现json数据与dict、object之间的高效转换,包括loads(),load(),dumps()... 项目中经常会用到json格式转为object对象、dict字典格式等。在此做个记录,方便后续用到该方

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

使用Java读取本地文件并转换为MultipartFile对象的方法

《使用Java读取本地文件并转换为MultipartFile对象的方法》在许多JavaWeb应用中,我们经常会遇到将本地文件上传至服务器或其他系统的需求,在这种场景下,MultipartFile对象非... 目录1. 基本需求2. 自定义 MultipartFile 类3. 实现代码4. 代码解析5. 自定

Java集合中的链表与结构详解

《Java集合中的链表与结构详解》链表是一种物理存储结构上非连续的存储结构,数据元素的逻辑顺序的通过链表中的引用链接次序实现,文章对比ArrayList与LinkedList的结构差异,详细讲解了链表... 目录一、链表概念与结构二、当向单链表的实现2.1 准备工作2.2 初始化链表2.3 打印数据、链表长

python连接sqlite3简单用法完整例子

《python连接sqlite3简单用法完整例子》SQLite3是一个内置的Python模块,可以通过Python的标准库轻松地使用,无需进行额外安装和配置,:本文主要介绍python连接sqli... 目录1. 连接到数据库2. 创建游标对象3. 创建表4. 插入数据5. 查询数据6. 更新数据7. 删除

Jenkins的安装与简单配置过程

《Jenkins的安装与简单配置过程》本文简述Jenkins在CentOS7.3上安装流程,包括Java环境配置、RPM包安装、修改JENKINS_HOME路径及权限、启动服务、插件安装与系统管理设置... 目录www.chinasem.cnJenkins安装访问并配置JenkinsJenkins配置邮件通知

Python用Flask封装API及调用详解

《Python用Flask封装API及调用详解》本文介绍Flask的优势(轻量、灵活、易扩展),对比GET/POST表单/JSON请求方式,涵盖错误处理、开发建议及生产环境部署注意事项... 目录一、Flask的优势一、基础设置二、GET请求方式服务端代码客户端调用三、POST表单方式服务端代码客户端调用四