java构建树形节点优化

引言:java中构建树形节点时,数据量小的话,可以随便些 ,不影响,但是当数据量大了以后,一棵大大的树,要半天才出来,所以就想着优化一下.

树形节点数据构建:

package me.zhengjie;

import ch.qos.logback.classic.joran.action.RootLoggerAction;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.aspectj.weaver.Lint;
import org.aspectj.weaver.ast.Var;
import org.hibernate.engine.query.spi.ReturnMetadata;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.CollectionUtils;
import sun.nio.cs.ext.TIS_620;

import java.io.Serializable;
import java.nio.file.NotDirectoryException;
import java.rmi.dgc.Lease;
import java.util.*;

/**
 * java构建树形结构
 * @author zls
 * @date 2019/12/26
 */
public class TreeTest {

    // 定义全局变量,统计地柜中总的循环次数
    private static int time;

    /**
     * 初始化数据,模拟从数据查询出来的数据
     * @return
     */
    public static List<Menu> initData() {
        List<Menu> menus = new ArrayList<>();

        menus.add(new Menu("0", "xxx公司", "", "1"));
        menus.add(new Menu("1", "财务部", "0", "2"));
        menus.add(new Menu("2", "人事部", "0", "2"));
        menus.add(new Menu("11", "财务部11", "1", "3"));
        menus.add(new Menu("12", "财务部12", "1", "3"));
        menus.add(new Menu("22", "财务部22", "2", "3"));
        menus.add(new Menu("21", "财务部21", "2", "3"));

        return menus;
    }

    public static void main(String[] args) {
        getTree();
    }

    /**
     * 构建树形结构
     */
    public static void getTree() {
        List<Menu> menus = initData();
        long start = System.currentTimeMillis();

        // 方法一
//        Menu root = new Menu();
//        Menu menu = buildNodes(root, menus);
//        System.out.println("JSON.toJSONString(root) = " + JSON.toJSONString(menu)); // 300s左右  递归循环了23次

        // 方法二
        Menu root1 = new Menu("0", "xxx公司", "", "1");
        buildNodes1(root1, menus); // 此处假设了根节点,如果再加上你去找根节点,那么此方法花费的时间可能更多
        System.out.println("JSON.toJSONString(root) = " + JSON.toJSONString(root1)); // 750s左右, 可能更多   递归循环了49次
        System.out.println("time = " + time);
        long end = System.currentTimeMillis();
        System.out.println("花费时间 = " + (end-start) +"毫秒");
    }

    /**
     * 方法二:构建子节点
     * @param commonModel
     * @param list
     */
    public static void buildNodes1(Menu commonModel, List<Menu> list) {
        list.forEach(l -> {
            time++;
            if (commonModel.getId().equalsIgnoreCase((String) l.getParentId())) {
                Menu c = new Menu();
                BeanUtils.copyProperties(l, c);
                buildNodes1(c, list);
                commonModel.getNodes().add(c);
            }
        });
    }

    /**
     * 方法一:构建子节点
     * @param root
     * @param nodes
     * @return
     */
    public static Menu buildNodes(Menu root, List<Menu> nodes) {

        // 剩余节点(还没有找到父节点的节点)
        ArrayList<Menu> remainNodes = new ArrayList<>();
        // 当前节点下的子节点
        ArrayList<Menu> child = new ArrayList<>();

        Iterator<Menu> iterator = nodes.iterator();
        while (iterator.hasNext()) {
            time++;
            Menu node = iterator.next();
            if (Objects.equals(node.getLevel(), "1")) {
                root = node;
                continue;
            }
            // 该节点找到了子节点
            if (Objects.equals(root.getId(), node.getParentId())) {
                child.add(node);
            } else {
                // 没有找到子节点
                remainNodes.add(node);
            }
        }
        // 根节点设置子节点
        root.setNodes(child);
        // 每一个节点再去寻找对应的子节点
        root.getNodes().stream().forEach(x -> {
            buildNodes(x, remainNodes);
        });
        return root;
    }
}

/**
 * 树形菜单
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
class Menu implements Serializable {
    private String id;
    private String name; // 菜单名称
    private String parentId; // 父id
    private String level; // 层级
    private List<Menu> nodes = new ArrayList<>(); // 子节点

    public Menu(String id, String name, String parentId, String level) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
        this.level = level;
    }

}

结果展示:

{
    "id":"0",
    "level":"1",
    "name":"xxx公司",
    "nodes":[
        {
            "id":"1",
            "level":"2",
            "name":"财务部",
            "nodes":[
                {
                    "id":"11",
                    "level":"3",
                    "name":"财务部11",
                    "nodes":[

                    ],
                    "parentId":"1"
                },
                {
                    "id":"12",
                    "level":"3",
                    "name":"财务部12",
                    "nodes":[

                    ],
                    "parentId":"1"
                }
            ],
            "parentId":"0"
        },
        {
            "id":"2",
            "level":"2",
            "name":"人事部",
            "nodes":[
                {
                    "id":"22",
                    "level":"3",
                    "name":"财务部22",
                    "nodes":[

                    ],
                    "parentId":"2"
                },
                {
                    "id":"21",
                    "level":"3",
                    "name":"财务部21",
                    "nodes":[

                    ],
                    "parentId":"2"
                }
            ],
            "parentId":"0"
        }
    ],
    "parentId":""
}

如有更优方案,请给出!!!

原文地址:https://www.cnblogs.com/shiyun32/p/12104949.html

时间: 2024-11-09 00:07:40

java构建树形节点优化的相关文章

Java构建树形菜单

构建树形菜单 效果图:支持多级菜单. 菜单实体类: public class Menu { // 菜单id private String id; // 菜单名称 private String name; // 父菜单id private String parentId; // 菜单url private String url; // 菜单图标 private String icon; // 菜单顺序 private int order; // 子菜单 private List<Menu> ch

java构建树形列表(带children属性)

一些前端框架提供的树形表格需要手动构建树形列表(带children属性的对象数组),这种结构一般是需要在Java后台构建好. 构建的方式是通过id字段与父id字段做关联,通过递归构建children字段来达到构建树形列表的目的. /** * 树形表格工具类 * * @author yanggb */ public class TreeTableUtil {/** * 把列表转换为树结构 * * @param originalList 原始list数据 * @param idFieldName 作

Erlang与C构建的节点通讯

Erlang节点之间的通讯,主要用于两个Erlang节点之间的通讯,但Erlang还支持与java构建的节点通讯,甚至与c构建的节点通讯,前面两种方式在我以前的文章都有讲到,所以这里讲Erlang与c构建的节点通讯. Cnode与erl_interface 想用C构建一个erlang节点,要利用Erlang的erl_interface接口来实现.c建立的节点,叫CNode ,其中,erl_interface除了实现一些基本的节点连接,消息发送接收,还实现Erlang Term 的构建解析. CN

探讨深入Java虚拟机之内存优化

上一篇我们讲述了Java虚拟机的体系结构和内存模型,那么我们就不得不说到内存泄露.大家都知道,Java是从C++的基础上发展而来的,而C++程序的很大的一个问题就是内存泄露难以解决,尽管Java的JVM有一套自己的垃圾回收机制来回收内存,在大多数的情况下并不需要java程序开发人员操太多的心,但也是存在泄露问题的,只是比C++小一点.比如说,程序中存在被引用但无用的对象:程序引用了该对象,但后续不会或者不能再使用它,那么它占用的内存空间就浪费了. 我们先来看看GC是如何工作的:监控每一个对象的运

java流的性能优化1-文件复制

传统的I/O速度相对比较慢,它会成为系统性能的瓶颈,所以在java1.4之后提供了NIO,它是一种全新的流:它具有以下特性: 1.为所有的原是类型提供Buffer缓存支持: 2.使用java.nio.charset.Charset作为字符编码解码解决方案: 3.增加通道(Channel)对象,作为新的原始I/O抽象: 4.支持锁和内存映射文件的文件访问接口: 5.提供基于Selector的异步网络I/O: NIO是一种全新的流,跟流式的I/O不同,NIO是基于块的,它以块为基本单位处理数据.在N

Java构建器模式

当创建对象需要传入多个参数的时候我们通常会根据参数的数量写不同的构造器,具体如下 public A(int a){} public A(int a, int b){} public A(int a, int b, int c){} 根据不同的参数调用不同的构造器,但是当参数多了的时候,这种方式不够灵活,所以会实现动态传参的方法 public A(){} public void seta(int a){} public void setb(int b){} public void setc(int

Gradle 笔记——Java构建入门

Gradle是一个通用的构建工具,通过它的构建脚本你可以构建任何你想要实现的东西,不过前提是你需要先写好构建脚本的代码.而大部分的项目,它们的构建流程基本是一样的,我们不必为每一个工程都编写它的构建代码,因为Gradle已经为我们提供了相应的插件.Gradle 本身自带了许多插件,而对于Gradle没有的插件,可以去github上看看有没有其他人实现,或自己实现.对Java项目而言,Gradle有Java插件,提供了像编译.测试.打包之类的功能. 这里简单介绍一下Java插件. Java插件为构

Java解读内存,优化编程

1.别用new Boolean 在很多场景中Boolean类型是必须的,比如JDBC中boolean类型的set与get都是通过Boolean封装传递的,大部分ORM也是用Boolean来封装boolean类型的,比如:       ps.setBoolean("isClosed",new Boolean(true));        ps.setBoolean("isClosed",new Boolean(isClosed));        ps.setBool

java对xml节点属性的增删改查

学习本文之前请先看我的另一篇文章JAVA对XML节点的操作可以对XML操作有更好的了解. 1 package vastsum; 2 3 import java.io.File; 4 import java.io.FileWriter; 5 import java.util.Iterator; 6 7 import org.dom4j.Attribute; 8 import org.dom4j.Document; 9 import org.dom4j.Element; 10 import org.