java 递归处理树形结构数据

简介: 在实战开发中经常有需要处理树形菜单、树形目录等等等业务需求。而对于这种产品,在设计数据库时也建议使用idparentId的结构来做。但是最终前端显示多用hightChart或者Echart插件来实现。

在实战开发中经常有需要处理树形菜单、树形目录等等等业务需求。而对于这种产品,在设计数据库时也建议使用id<----->parentId的结构来做。但是最终前端显示多用hightChart或者Echart插件来实现。所以在给前端数据时,最好的做法就是把数据库结构话的数据处理成treeJson格式。本文就简单介绍以递归方式处理此数据。

数据库表结构

id name type parentId
1 root 1 0
2 a 1 1
3 b 1 1
4 c 1 1
5 d 1 2
6 e 1 2
7 f 1 3
8 g 1 7

最终想要的效果

img_4a13b0417a90d742850886c9b4d06a13.png
image.png

java 递归实现代码

package com.br.usercenter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.map.HashedMap;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author jack cooper
 * @create 2017-09-15 16:53
 */
public class TreeRecursion {

    public static void main(String[] args) {

        Map<String,Node> nodes = new HashedMap();
        //模拟数据库存储树结构
        nodes.put("1",new Node("1","root",1,"0"));
        nodes.put("2",new Node("2","a",1,"1"));
        nodes.put("3",new Node("3","b",1,"1"));
        nodes.put("4",new Node("4","c",1,"1"));
        nodes.put("5",new Node("5","d",1,"2"));
        nodes.put("6",new Node("6","e",1,"2"));
        nodes.put("7",new Node("7","f",1,"3"));
        nodes.put("8",new Node("8","g",1,"7"));
        System.out.println("result:" + JSON.toJSONString(getNodeJson("0",nodes)));
    }

    /**
     * 递归处理   数据库树结构数据->树形json
     * @param nodeId
     * @param nodes
     * @return
     */
    public static JSONArray getNodeJson(String nodeId, Map<String,Node> nodes){

        //当前层级当前node对象
        Node cur = nodes.get(nodeId);
        //当前层级当前点下的所有子节点(实战中不要慢慢去查,一次加载到集合然后慢慢处理)
        List<Node> childList = getChildNodes(nodeId,nodes);

        JSONArray childTree = new JSONArray();
        for (Node node : childList) {
            JSONObject o = new JSONObject();
            o.put("name", node.getName());
            o.put("type", node.getType());
            JSONArray childs = getNodeJson(node.getId(),nodes);  //递归调用该方法
            if(!childs.isEmpty()) {
                o.put("children",childs);
            }
            childTree.fluentAdd(o);
        }
        return childTree;
    }

    /**
     * 获取当前节点的所有子节点
     * @param nodeId
     * @param nodes
     * @return
     */
    public static List<Node> getChildNodes(String nodeId, Map<String,Node> nodes){
        List<Node> list = new ArrayList<>();
        for (String key : nodes.keySet() ) {
            if(nodes.get(key).getParentId().equals(nodeId)){
                list.add(nodes.get(key));
            }
        }
        return list;
    }

}


class Node{
    public String id ;
    public String name;
    public Integer type;
    public String parentId;

    public Node(String id, String name, Integer type, String parentId) {
        this.id = id;
        this.name = name;
        this.type = type;
        this.parentId = parentId;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public String getParentId() {
        return parentId;
    }

    public void setParentId(String parentId) {
        this.parentId = parentId;
    }
}

最终结果json

[
    {
        "children": [
            {
                "children": [
                    {
                        "children": [
                            {
                                "name": "g",
                                "type": 1
                            }
                        ],
                        "name": "f",
                        "type": 1
                    }
                ],
                "name": "b",
                "type": 1
            },
            {
                "children": [
                    {
                        "name": "d",
                        "type": 1
                    },
                    {
                        "name": "e",
                        "type": 1
                    }
                ],
                "name": "a",
                "type": 1
            },
            {
                "name": "c",
                "type": 1
            }
        ],
        "name": "root",
        "type": 1
    }
]

用echart处理最终效果

访问http://echarts.baidu.com/echarts2/doc/example/tree1.html
在左侧json中找到data节点,将value替换成上述json。点击刷新即可。

相关文章
|
10天前
|
Java 程序员 容器
Java中的变量和常量:数据的‘小盒子’和‘铁盒子’有啥不一样?
在Java中,变量是一个可以随时改变的数据容器,类似于一个可以反复打开的小盒子。定义变量时需指定数据类型和名称。例如:`int age = 25;` 表示定义一个整数类型的变量 `age`,初始值为25。 常量则是不可改变的数据容器,类似于一个锁死的铁盒子,定义时使用 `final` 关键字。例如:`final int MAX_SPEED = 120;` 表示定义一个名为 `MAX_SPEED` 的常量,值为120,且不能修改。 变量和常量的主要区别在于变量的数据可以随时修改,而常量的数据一旦确定就不能改变。常量主要用于防止意外修改、提高代码可读性和便于维护。
|
11天前
|
存储 缓存 安全
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见。本文介绍了使用 `File.createTempFile` 方法和自定义创建临时文件的两种方式,详细探讨了它们的使用场景和注意事项,包括数据缓存、文件上传下载和日志记录等。强调了清理临时文件、确保文件名唯一性和合理设置文件权限的重要性。
28 2
|
11天前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
21 2
|
15天前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
38 2
|
21天前
|
SQL Java OLAP
java实现“数据平滑升级”
java实现“数据平滑升级”
39 2
|
26天前
|
SQL Java 关系型数据库
java连接mysql查询数据(基础版,无框架)
【10月更文挑战第12天】该示例展示了如何使用Java通过JDBC连接MySQL数据库并查询数据。首先在项目中引入`mysql-connector-java`依赖,然后通过`JdbcUtil`类中的`main`方法实现数据库连接、执行SQL查询及结果处理,最后关闭相关资源。
|
22天前
|
SQL Java OLAP
java实现“数据平滑升级”
java实现“数据平滑升级”
13 0
JAVA 递归文件夹
private void getAllFileInfo(String path) { File dirFile = new File(path); File[] files = dirFile.
703 0
下一篇
无影云桌面