惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
B
Blog RSS Feed
L
LangChain Blog
Jina AI
Jina AI
爱范儿
爱范儿
C
Check Point Blog
云风的 BLOG
云风的 BLOG
Last Week in AI
Last Week in AI
月光博客
月光博客
GbyAI
GbyAI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Stack Overflow Blog
Stack Overflow Blog
V
V2EX
A
About on SuperTechFans
有赞技术团队
有赞技术团队
Microsoft Azure Blog
Microsoft Azure Blog
The GitHub Blog
The GitHub Blog
博客园 - Franky
Apple Machine Learning Research
Apple Machine Learning Research
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google DeepMind News
Google DeepMind News
博客园 - 三生石上(FineUI控件)
S
SegmentFault 最新的问题

博客园 - 江城2211

大数值的精度与格式化显示问题 【知识总结】数据库的事务、并发与锁管理 基于数据源连接,动态构造JPA上下文EntityManager 【转载】使用了HTTPS为啥还要接口数据加密? RSA加密算法,加解密、签名示例 国密SM2算法,加密、签名示例 【知识总结】JVM线程堆栈中的基础概念解读 【问题记录】JVM进程崩溃(hs_err_pid.log致命错误日志) [问题记录】存在视图依赖的数据表,DDL修改字段比如做扩容等注意事项 【编码技巧】批量校验或处理关联引用数据的优化总结 【问题总结】Garmin路线无法同步和地图坐标偏移的解决办法 【工具推荐】磁盘IO检测工具之Diskspd 【编程技巧】SQL脚本快速生成随机测试数据 【编程技巧】结合JPA通用分页与排序技术,支持百万级以上数据的DML批量处理方案 【使用技巧】CodeDecom.exe批量反编译JAR包+Beyond Compare对比 【问题记录】Cause: java.sql.SQLRecoverableException: No more data to read from socket JDBC与各数据库产品连接的驱动及URL示例 【问题记录】使用PowerDesigner连接数据库并反向工程生成所有表及关系 使用tcpdump抓取网络包,在wareshark查看对应请求及响应的原始报文
【编码技巧】总结一个稳定而高效的方法,将二维关系数据转换...
江城2211 · 2024-07-30 · via 博客园 - 江城2211

        产品或项目开发过程中,经常遇到一些存在上下级关系的树形结构,但在数据库中存储为二维表关系数据的情况。而前端树形控件又要求按照树形层级组织数据,这就存在一个平铺的关系数据转换为树形层级结构的典型问题。

       表结构及二维数据示例(以id,parentid自关联为例):

Create Table TreeData(id varchar(36), code varchar(50), name narchar(100), parentid varchar(36));

[{id: "", code: "", name: "", parentid: ""}]

       期望的数据示例:

[{
        id: "",
        code: "",
        name: "",
        parentid: "",
        subNodes: [{
                id: "",
                code: "",
                name: "",
                parentid: "",
                subNodes: []
            }
        ]
    }
]

       在实际编码过程,我们可以采用嵌套循环或递归等方式处理,但如果遇到数据量较大、层级较深且层级不固定等场景,此种实现性能不佳。从时间复杂度来说,是O(n2).

       之前在几次性能优化时,采用过一个方法,先构造全量数据的HashMap,然后再快速将自身加到父对象的子节点集合,此方式性能稳定、时间复杂度为O(n),经过实际验证效果也不错(5k节点时间消耗从>700ms优化到<100ms),在此记录备忘。

import lombok.Data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
public class Func {
    private String id;
    private String code;
    private String name;
    private String parentId;
    private List<Func> subNodes;

    public List<Func> BuildTreeData(List<Func> orignList) {
        Map<String, Func> allMap = new HashMap<>();
        List<Func> rootList = new ArrayList<>();
        for (Func func : orignList) {
            allMap.put(func.getId(), func);
        }

        for (Map.Entry<String, Func> map : allMap.entrySet()) {
            if (allMap.containsKey(map.getValue().getParentId())) {
                Func parent = allMap.get(map.getValue().getParentId());
                if (parent.getSubNodes() == null) {
                    parent.setSubNodes(new ArrayList<>());
                }
                parent.getSubNodes().add(map.getValue());
            } else {
                rootList.add(map.getValue());
            }
        }

        return rootList;
    }
}