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

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

相关文章

idea如何开启菜单栏

《idea如何开启菜单栏》文章介绍了如何通过修改IntelliJIDEA的样式文件`ui.lnf.xml`来重新显示被关闭的菜单栏,并分享了解决问题的步骤... 目录ijsdea开启菜单栏第一步第二步总结idea开启菜单栏手贱关闭了idea的js菜单栏,花费了半个小时终于解决,记录并分享一下第一步找

使用IntelliJ IDEA创建简单的Java Web项目完整步骤

《使用IntelliJIDEA创建简单的JavaWeb项目完整步骤》:本文主要介绍如何使用IntelliJIDEA创建一个简单的JavaWeb项目,实现登录、注册和查看用户列表功能,使用Se... 目录前置准备项目功能实现步骤1. 创建项目2. 配置 Tomcat3. 项目文件结构4. 创建数据库和表5.

Python 标准库time时间的访问和转换问题小结

《Python标准库time时间的访问和转换问题小结》time模块为Python提供了处理时间和日期的多种功能,适用于多种与时间相关的场景,包括获取当前时间、格式化时间、暂停程序执行、计算程序运行时... 目录模块介绍使用场景主要类主要函数 - time()- sleep()- localtime()- g

使用PyQt5编写一个简单的取色器

《使用PyQt5编写一个简单的取色器》:本文主要介绍PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16进制颜色编码,一款跟随鼠标刷新图像的RGB和16... 目录取色器1取色器2PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16

四种简单方法 轻松进入电脑主板 BIOS 或 UEFI 固件设置

《四种简单方法轻松进入电脑主板BIOS或UEFI固件设置》设置BIOS/UEFI是计算机维护和管理中的一项重要任务,它允许用户配置计算机的启动选项、硬件设置和其他关键参数,该怎么进入呢?下面... 随着计算机技术的发展,大多数主流 PC 和笔记本已经从传统 BIOS 转向了 UEFI 固件。很多时候,我们也

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

Java中switch-case结构的使用方法举例详解

《Java中switch-case结构的使用方法举例详解》:本文主要介绍Java中switch-case结构使用的相关资料,switch-case结构是Java中处理多个分支条件的一种有效方式,它... 目录前言一、switch-case结构的基本语法二、使用示例三、注意事项四、总结前言对于Java初学者

结构体和联合体的区别及说明

《结构体和联合体的区别及说明》文章主要介绍了C语言中的结构体和联合体,结构体是一种自定义的复合数据类型,可以包含多个成员,每个成员可以是不同的数据类型,联合体是一种特殊的数据结构,可以在内存中共享同一... 目录结构体和联合体的区别1. 结构体(Struct)2. 联合体(Union)3. 联合体与结构体的

Java将时间戳转换为Date对象的方法小结

《Java将时间戳转换为Date对象的方法小结》在Java编程中,处理日期和时间是一个常见需求,特别是在处理网络通信或者数据库操作时,本文主要为大家整理了Java中将时间戳转换为Date对象的方法... 目录1. 理解时间戳2. Date 类的构造函数3. 转换示例4. 处理可能的异常5. 考虑时区问题6.