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。点击刷新即可。

相关文章
|
1月前
|
前端开发 JavaScript Java
java常用数据判空、比较和类型转换
本文介绍了Java开发中常见的数据处理技巧,包括数据判空、数据比较和类型转换。详细讲解了字符串、Integer、对象、List、Map、Set及数组的判空方法,推荐使用工具类如StringUtils、Objects等。同时,讨论了基本数据类型与引用数据类型的比较方法,以及自动类型转换和强制类型转换的规则。最后,提供了数值类型与字符串互相转换的具体示例。
|
4天前
|
存储 分布式计算 Hadoop
基于Java的Hadoop文件处理系统:高效分布式数据解析与存储
本文介绍了如何借鉴Hadoop的设计思想,使用Java实现其核心功能MapReduce,解决海量数据处理问题。通过类比图书馆管理系统,详细解释了Hadoop的两大组件:HDFS(分布式文件系统)和MapReduce(分布式计算模型)。具体实现了单词统计任务,并扩展支持CSV和JSON格式的数据解析。为了提升性能,引入了Combiner减少中间数据传输,以及自定义Partitioner解决数据倾斜问题。最后总结了Hadoop在大数据处理中的重要性,鼓励Java开发者学习Hadoop以拓展技术边界。
28 7
|
17天前
|
存储 Java BI
java怎么统计每个项目下的每个类别的数据
通过本文,我们详细介绍了如何在Java中统计每个项目下的每个类别的数据,包括数据模型设计、数据存储和统计方法。通过定义 `Category`和 `Project`类,并使用 `ProjectManager`类进行管理,可以轻松实现项目和类别的数据统计。希望本文能够帮助您理解和实现类似的统计需求。
68 17
|
2月前
|
JSON Java 程序员
Java|如何用一个统一结构接收成员名称不固定的数据
本文介绍了一种 Java 中如何用一个统一结构接收成员名称不固定的数据的方法。
39 3
|
2月前
|
Java 程序员 容器
Java中的变量和常量:数据的‘小盒子’和‘铁盒子’有啥不一样?
在Java中,变量是一个可以随时改变的数据容器,类似于一个可以反复打开的小盒子。定义变量时需指定数据类型和名称。例如:`int age = 25;` 表示定义一个整数类型的变量 `age`,初始值为25。 常量则是不可改变的数据容器,类似于一个锁死的铁盒子,定义时使用 `final` 关键字。例如:`final int MAX_SPEED = 120;` 表示定义一个名为 `MAX_SPEED` 的常量,值为120,且不能修改。 变量和常量的主要区别在于变量的数据可以随时修改,而常量的数据一旦确定就不能改变。常量主要用于防止意外修改、提高代码可读性和便于维护。
|
2月前
|
存储 缓存 安全
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见。本文介绍了使用 `File.createTempFile` 方法和自定义创建临时文件的两种方式,详细探讨了它们的使用场景和注意事项,包括数据缓存、文件上传下载和日志记录等。强调了清理临时文件、确保文件名唯一性和合理设置文件权限的重要性。
212 2
|
2月前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
45 2
JAVA 递归文件夹
private void getAllFileInfo(String path) { File dirFile = new File(path); File[] files = dirFile.
708 0