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

推荐订阅源

爱范儿
爱范儿
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
G
GRAHAM CLULEY
www.infosecurity-magazine.com
www.infosecurity-magazine.com
V2EX - 技术
V2EX - 技术
The Last Watchdog
The Last Watchdog
S
Secure Thoughts
Webroot Blog
Webroot Blog
PCI Perspectives
PCI Perspectives
L
LINUX DO - 最新话题
Hacker News: Ask HN
Hacker News: Ask HN
N
News and Events Feed by Topic
H
Heimdal Security Blog
H
Help Net Security
T
The Blog of Author Tim Ferriss
P
Proofpoint News Feed
The GitHub Blog
The GitHub Blog
Jina AI
Jina AI
Recent Commits to openclaw:main
Recent Commits to openclaw:main
F
Full Disclosure
小众软件
小众软件
S
Securelist
罗磊的独立博客
NISL@THU
NISL@THU
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cisco Blogs
云风的 BLOG
云风的 BLOG
C
CERT Recently Published Vulnerability Notes
Cisco Talos Blog
Cisco Talos Blog
Know Your Adversary
Know Your Adversary
S
Schneier on Security
D
DataBreaches.Net
M
MIT News - Artificial intelligence
V
Vulnerabilities – Threatpost
N
News and Events Feed by Topic
有赞技术团队
有赞技术团队
F
Fortinet All Blogs
T
Tenable Blog
The Register - Security
The Register - Security
C
Check Point Blog
AWS News Blog
AWS News Blog
Cloudbric
Cloudbric
C
CXSECURITY Database RSS Feed - CXSecurity.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Google Online Security Blog
Google Online Security Blog
博客园 - 叶小钗
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - 司徒正美

博客园 - 江城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;
    }
}