树形结构的一种便捷实现方案

背景

在开发过程中经常需要把平铺的数据结构转为树形的数据结构,例如多级菜单、组织机构等。

实现方案有很多种。

1、可以使用递归查询,但是这样数据一多会导致频繁的多次查询数据库,产生很多额外的IO开销,总体的响应时间会比较慢,一般不会这样做。

2、可以事先查询出来所有的数据,再进行递归的子节点查找,这是一个可行的方案,只需要查询一次数据库,之后的操作利用算法在内存操作,这样响应时间会有一个很大的提升。

3、这里要说的一种方案和第二种类似,只不过采用了google的guava包下的Multimap这种数据结构,利用它可以一个key对应多个值的特性。

方案实现

引入guava包

java 复制代码
<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava</artifactId>
    <version>33.2.0-jre</version>
</dependency>

<!-- 这个包可以不要,这里我用来转json字符串打印出来有用到 -->
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.83</version>
</dependency>

树形VO

java 复制代码
@Data
public class TreeVO {

    private List<TreeVO> children;
    private int id;
    private boolean leaf;
    private String menuName;
    private int parentId;
}

转树示例代码

java 复制代码
public static void main(String[] args) {
		TreeVO v1 = new TreeVO();
		v1.setId(10L);
		v1.setParentId(0L);
		v1.setMenuName("第一级菜单");

		TreeVO  v2 = new TreeVO();
		v2.setId(11L);
		v2.setParentId(10L);
		v2.setMenuName("第二级菜单1");

		TreeVO v21 = new TreeVO();
		v21.setId(12L);
		v21.setParentId(10L);
		v21.setMenuName("第二级菜单2");

		TreeVO v3 = new TreeVO();
		v3.setId(21L);
		v3.setParentId(11L);
		v3.setMenuName("第三级菜单");

		Multimap<Long,TreeVO> multimap = ArrayListMultimap.create();
		multimap.put(v1.getParentId(),v1);
		multimap.put(v2.getParentId(),v2);
		multimap.put(v21.getParentId(),v21);
		multimap.put(v3.getParentId(),v3);

		Iterator<TreeVO> iterator = multimap.values().iterator();
		while (iterator.hasNext()) {
			TreeVOmenuNode = iterator.next();
			// 找直接后代 children
			Collection<TreeVO> children = multimap.get(menuNode.getId());
			if (children.isEmpty()) {
				menuNode.setLeaf(true);
				menuNode.setChildren(null);
			} else {
				menuNode.setChildren(children);
			}
		}
		System.out.println(JSON.toJSONString(multimap.get(0L),SerializerFeature.PrettyFormat));
	}

这里打印出来的结果是

{ "children":\[ { "children":\[ { "id":21, "leaf":true, "menuName":"第三级菜单", "parentId":11 } \], "id":11, "leaf":false, "menuName":"第二级菜单1", "parentId":10 }, { "id":12, "leaf":true, "menuName":"第二级菜单2", "parentId":10 } \], "id":10, "leaf":false, "menuName":"第一级菜单", "parentId":0 }

相关推荐
linweidong6 小时前
中科闻歌Java面试题及参考答案
java·python·大模型·提示词·ai agent·mcp·rag原理
OpenAnolis小助手6 小时前
一句话看透 JVM,SysOM 诊断 Skill 新增 Java 应用诊断能力
java·开发语言·jvm·阿里云·操作系统控制台·sysom
ForteScarlet6 小时前
Kotlin 2.4.20 现已发布,新特性多不多?
android·java·开发语言·开源·kotlin·jetbrains
萧瑟余晖6 小时前
Java深入解析篇六十二之安全机制详解
java·开发语言
小刘在重生~7 小时前
Java 常用类|包装类 装箱拆箱、Integer 缓存面试题
java·python·缓存
Orange_sparkle7 小时前
Pi Agent vs LangGraph:从人机交互、企业 RAG 到持久化工作流的完整选型指南
java·网络·人机交互
Wang's Blog8 小时前
Java框架快速入门: Spring Security+OAuth2之过滤器与过滤器链
java·开发语言·spring
谢尔登9 小时前
01_Java基础速通
java·开发语言
lemon_sjdk9 小时前
javafx-Image图像(2)
java·javafx
小七在进步9 小时前
C++入门(2)
java·jvm·c++