树形结构转换工具类

news/2025/11/19 14:27:03/文章来源:https://www.cnblogs.com/huang1108/p/19242302

项目中使用了很多树状结构,为了方便使用开发一个通用的工具类。

使用工具类的时候写一个类基础BaseNode,如果有个性化字段添加到类里面,然后就可以套用工具类。

工具类会将id和pid做关联返回一个树状结构的集合。使用了hutool的工具包判空。

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.25</version>
</dependency>

TreeUtil.java

import cn.hutool.core.util.ObjUtil;
import com.iccb.BaseNode;import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;public class TreeUtil {public static <T extends BaseNode<T>> List<T> toTree(List<T> treeNodeList) {//数据按照pid分组Map<Long, List<T>> map = treeNodeList.stream().collect(Collectors.groupingBy(T :: getPid,LinkedHashMap::new,Collectors.toList()));//找出所有的根节点,pid=-1的为根节点List<T> areaList = map.get(-1L);if(ObjUtil.isEmpty(areaList)){return new ArrayList<>();}for (T areaVO : areaList) {forEach(map, areaVO);}return areaList;}private static  <T extends BaseNode<T>> void forEach(Map<Long, List<T>> collect, T areaVO) {List<T> nodeList = collect.get(areaVO.getId());if (collect.get(areaVO.getId()) == null) {return;}areaVO.setChildren(nodeList);for (T node : nodeList) {forEach(collect, node);}}}

BaseNode.java

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.util.List;/*** @author admin*/
@Data
public class BaseNode<T> implements Serializable {private static final long serialVersionUID = 1L;@JsonFormat(shape = JsonFormat.Shape.STRING)private Long id;@JsonFormat(shape = JsonFormat.Shape.STRING)private Long pid;private String value;private List<T> children;
}

 使用范例

返回树状结构的地区数据

1)首先构建数据VO

@EqualsAndHashCode(callSuper = true)
@Data
public class AreaVO extends BaseNode<AreaVO> {private static final long serialVersionUID = 1L;private String areaCode;private String label;private String level;private String lnglat;}

2)查询地区数据

List<Area> list = areaService.list();

3) 构建数据VO 或者 直接使用mapper查询用VO封装

List<AreaVO> collect = list.stream().map(i -> {AreaVO areaVO = BeanUtil.copyProperties(i, AreaVO.class);areaVO.setLabel(i.getAreaName());areaVO.setValue(String.valueOf(i.getId()));areaVO.setLevel(i.getAreaLevel());areaVO.setPid(i.getParentId());return areaVO;
}).collect(Collectors.toList());

4) 使用工具类构造数据结构

List<AreaVO> areaTree = TreeUtil.toTree(collect);

返回数据示例

查看代码
 {"code": 200,"msg": null,"data": [{"id": "4058069977868140544","value": "4058069977868140544","pid": "4058069977868148888","children": [{"id": "4058069978245627904","value": "4058069978245627904","pid": "4058069977868140544","children": [{"id": "4058069978530840576","value": "4058069978530840576","pid": "4058069978245627904","children": null,"areaCode": "110101000000","label": "东城区","level": "3","lnglat": null},{"id": "4058069978979631104","value": "4058069978979631104","pid": "4058069978245627904","children": null,"areaCode": "110106000000","label": "丰台区","level": "3","lnglat": null},{"id": "4058069979046739968","value": "4058069979046739968","pid": "4058069978245627904","children": null,"areaCode": "110107000000","label": "石景山区","level": "3","lnglat": null},{"id": "4058069979118043136","value": "4058069979118043136","pid": "4058069978245627904","children": null,"areaCode": "110108000000","label": "海淀区","level": "3","lnglat": null},{"id": "4058069979650719744","value": "4058069979650719744","pid": "4058069978245627904","children": null,"areaCode": "110114000000","label": "昌平区","level": "3","lnglat": null},{"id": "4058069979747188736","value": "4058069979747188736","pid": "4058069978245627904","children": null,"areaCode": "110115000000","label": "大兴区","level": "3","lnglat": null},{"id": "4058069979852046336","value": "4058069979852046336","pid": "4058069978245627904","children": null,"areaCode": "110116000000","label": "怀柔区","level": "3","lnglat": null},{"id": "4058069980284059648","value": "4058069980284059648","pid": "4058069978245627904","children": null,"areaCode": "110229000000","label": "延庆区","level": "3","lnglat": null}],"areaCode": "110100000000","label": "北京市","level": "2","lnglat": null}],"areaCode": "110000000000","label": "北京市","level": "1","lnglat": null},{"id": "4058069980422471680","value": "4058069980422471680","pid": "4058069977868148888","children": [{"id": "4058069980527329280","value": "4058069980527329280","pid": "4058069980422471680","children": [{"id": "4058069980627992576","value": "4058069980627992576","pid": "4058069980527329280","children": null,"areaCode": "120101000000","label": "和平区","level": "3","lnglat": null},{"id": "4058069980732850176","value": "4058069980732850176","pid": "4058069980527329280","children": null,"areaCode": "120102000000","label": "河东区","level": "3","lnglat": null},{"id": "4058069980841902080","value": "4058069980841902080","pid": "4058069980527329280","children": null,"areaCode": "120103000000","label": "河西区","level": "3","lnglat": null},{"id": "4058069981148086272","value": "4058069981148086272","pid": "4058069980527329280","children": null,"areaCode": "120106000000","label": "红桥区","level": "3","lnglat": null},{"id": "4058069981252943872","value": "4058069981252943872","pid": "4058069980527329280","children": null,"areaCode": "120110000000","label": "东丽区","level": "3","lnglat": null},{"id": "4058069981357801472","value": "4058069981357801472","pid": "4058069980527329280","children": null,"areaCode": "120111000000","label": "西青区","level": "3","lnglat": null}],"areaCode": "120100000000","label": "天津市","level": "2","lnglat": null}],"areaCode": "120000000000","label": "天津市","level": "1","lnglat": null},{"id": "4461100398823866368","value": "4461100398823866368","pid": "4058069977868148888","children": [{"id": "4461100398974861312","value": "4461100398974861312","pid": "4461100398823866368","children": null,"areaCode": "820100000000","label": "澳门半岛","level": "2","lnglat": null},{"id": "4461100399113273344","value": "4461100399113273344","pid": "4461100398823866368","children": null,"areaCode": "820200000000","label": "离岛","level": "2","lnglat": null}],"areaCode": "820000000000","label": "澳门特别行政区","level": "1","lnglat": null}]
}

 

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

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

相关文章

完整教程:解读ASME BPVC.II.A-2023

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

linux drcom

您提到的 + #引号 + drcom + #引号 + 可能是某个特定软件或服务的名称,但根据常见的 Linux 系统和相关技术, + #引号 + drcom + #引号 + 并不是一个标准的 Linux 命令或工具。可能是以下几种情况之一:1.…

linux doxygen

在 Linux 系统中,doxygen 是一个常用的文档生成工具,主要用于从 C/C++ 代码中自动生成 API 文档。如果你想要在 Linux 系统中使用 doxygen,可以按照以下步骤进行操作:? 一、安装 Doxygen 1. 使用包管理器安装(适…

NetworkManager接管vxlan网卡等导致容器网络不通

表格 复制 检查方式 结果含义 nmcli device status 中 vxlan 接口为 unmanaged 未接管 nmcli connection show 中有 vxlan 配置 已接管 ip link 能看到接口但 nmcli 看不到 手动创建,未接管 // 确认有类似…

2025年生芝麻去石机订做厂家权威推荐榜单:生芝麻清理机/全自动洗芝麻机/芝麻清选机源头厂家精选

在粮油加工行业持续升级的背景下,生芝麻去石机作为芝麻预处理的核心设备,其性能直接影响芝麻制品的品质与安全。据行业统计,2025年全球芝麻加工设备市场规模预计达85亿元,其中智能化清理设备需求增长显著。为帮助用…

linux do while

在 Linux 中,没有直接的 do-while 循环结构,这是伪代码或特定语言(如 C、C++、Java 等)中的语法。在 Bash 脚本中,可以使用 while 循环来模拟 do-while 的行为。? 伪代码(C/C++风格): do {// 代码块 } while …

OpenCVSharp:使用三种不同的局部二值化算法

概述 局部二值化(Local Binarization)是一种图像处理技术,用于将灰度图像转换为二值图像(黑白图像)。与全局二值化不同,局部二值化不是对整个图像使用单一阈值,而是根据图像中每个像素周围的局部区域特征来动态…

linux dns重启

在 Linux 系统中,如果你想要重启 DNS 服务,通常是指重启 named(BIND)、dnsmasq 或 systemd-resolved 等 DNS 服务。以下是几种常见场景下的重启方法:? 1. 重启 named(BIND)服务(适用于 Debian/Ubuntu 系统) …

电流互感器:电力系统中的“智慧之眼”与应用全景

电流互感器通过电磁感应将大电流转换为小电流,实现安全测量与智能控制,广泛应用于电力系统各环节。在庞大而复杂的电力系统中,如何安全、精准地测量高达数十万安培的电流?如何确保从发电厂到千家万户的用电安全?在…

ICPC2025沈阳 游记

准备打星去打铁关了。省流 准备打星去打铁关了。11.16 内含剧透,请vp后再来。 不是题解!!!!!!! 赛前 东北挺好的。 赛时 通过看气球颜色法一眼发现 I 题是签,直接丢给俩队友。吃了一罚,真无所谓吧。 随便翻翻…

IT项目管理流程梳理

IT项目管理流程梳理目录IT项目的定义约束条件(范围)干系人IT项目阶段划分Reference下文梳理的都是一般性的IT项目管理流程,涉及对项目阶段的划分,每阶段内所涉及的事项等。IT项目的定义 信息技术(Information Tec…

环境试验设备选购避坑指南:2025年度三大实力厂商深度测评

在航空、航天、新能源、电子等高端制造领域,环境试验设备的可靠性直接决定了产品研发的质量与效率。面对市场上琳琅满目的品牌,如何选择一家技术过硬、服务可靠且性价比高的长期合作伙伴,成为众多工程师与采购负责人…

北京旅行社哪家靠谱?本地口碑机构实力对比

在北京选择旅行社时,许多人会关注服务质量、线路规划及用户口碑。随着旅游市场的多样化发展,本地旅行社在资质、行程安排和售后保障等方面呈现不同特色,了解其核心优势有助于找到适合自己的出行伙伴。 一、北京旅行…

开源无界,能效有解:MyEMS,让每一度能源都被精准掌控

当全球能源局势进入 “紧平衡” 时代,企业面临的不仅是 “用能成本高” 的现实压力,更有 “能耗管理粗放”“数据孤岛严重”“节能潜力难挖掘” 的深层困境 —— 传统闭源能源管理系统要么成本高昂、定制化难,要么功…

2025年沧州爱采购运营公司权威推荐榜单:电商代运营/阿里代运营/短视频运营服务商精选

在数字经济快速发展的背景下,企业对于专业化、数据驱动的网络运营服务需求日益增长。沧州地区作为华北地区重要的产业聚集地,涌现出一批专注于企业网络运营服务的优秀公司。本文结合行业调研数据、服务覆盖范围及客户…

从零使用vue脚手架制作一个简易的计算器

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Playwright_API

1. from playwright.sync_api import expectexpect(page.get_by_text("Products")).to_be_visible(), 这样不会报错 2. from playwright.sync_api import expectbutton = page.get_by_role("button&quo…

完整教程:全面解读大型语言模型测评:从认知演进到实操框架

完整教程:全面解读大型语言模型测评:从认知演进到实操框架pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Conso…

Redis之String 类型入门与实战,由基础语法快速掌握再到缓存加速/验证码防刷/计数统计场景应用 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

公众号怎么上传附件?使用快存文档支持word,excel,pdf格式。

快存文档(kuaidoc.cn) 在公众文章里上传附件。 这是一个非常实用的功能,特别适合在公众号文章中添加 Word、Excel、PDF 等文档附件。"快存文档"(kuaidoc.cn) 在公众文章里上传附件。 这是一个非常实用的功能…