树形图-以前用递归,现在用Hutool工具类TreeUtil

本文介绍了如何使用Hutool的TreeUtil工具库快速解析和构建树形数据结构,通过示例展示了如何避免递归查询带来的资源消耗,实现在内存中一次性处理复杂层级的数据。

pom.xml中要引入:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.3.5</version>
</dependency>

对于树形结构的实现方法可以用递归,我开始用的也是递归,但是有一个很大的问题,那就是查询

次数太多。所以我们为了节省资源以及时间,我们最好能够一次查询,在内存中对树形数据进行解

析。 

package com.zs.boot.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;

public class Testtree {
   /* @Test
    public void test03(){
        List<Recursion> list = new ArrayList<>();
        list.add(new Recursion(1L, "A", 0L,"111",new Date()));
        list.add(new Recursion(2L, "B", 0L,"22",new Date()));
        list.add(new Recursion(3L, "C", 1L,"333",new Date()));
        list.add(new Recursion(4L, "D", 1L,"444",new Date()));
        list.add(new Recursion(5L, "E", 3L,"555",new Date()));
        list.add(new Recursion(6L, "F", 4L,"666",new Date()));
        List<TreeNode<Long>> collect = list.stream().map(recursion -> {
            Map<String, Object> map = new HashMap<>();
            map.put("text", recursion.getText());
            map.put("createDate", recursion.getCreateDate());
            TreeNode<Long> treeNode = new TreeNode<Long>().setId(recursion.getId())
                    .setName(recursion.getName())
                    .setParentId(recursion.getPid())
//                    .setWeight(fileCategoryDO.getSort())
                    .setExtra(map);
            return treeNode;
        }).collect(Collectors.toList());
        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名 都要默认值的
//        treeNodeConfig.setWeightKey("orderNum");
        treeNodeConfig.setIdKey("id");
        treeNodeConfig.setChildrenKey("childrenNode");
        // 最大递归深度
        treeNodeConfig.setDeep(9);
        // 构建node列表
        List<TreeNode<String>> nodeList = CollUtil.newArrayList();
        //转换器
        List<Tree<String>> treeNodes = TreeUtil.build(collect, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId()+"");
                    tree.setParentId(treeNode.getParentId()+"");
//                    tree.setWeight(treeNode.getWeight());
                    tree.setName(treeNode.getName());
                    // 扩展属性 ...
//                    tree.putExtra("level", treeNode.getExtra().getOrDefault("level", 2));
                    tree.putExtra("text", treeNode.getExtra().getOrDefault("text", null));
                    tree.putExtra("createDate", treeNode.getExtra().getOrDefault("createDate", null));
                });
        System.out.println(JSONUtil.parse(treeNodes));
        //List<Long> treeId = getTreeId(list, 3L);
        //System.out.println(treeId);
    }*/

    /*public static JSON main(String[] args) {
        // 查询数据
        List<LxhpArea> areaList = areaService.list();
        // 构建的整个树数据
        List<TreeNode<String>> treeNodeList = areaList.stream().map(area -> {
            // 扩展字段赋值,下面要取这里的值
            Map<String, Object> extraMap = new HashMap<>();
            extraMap.put("domain", area.getDomain());
            extraMap.put("isOpen", area.getIsOpen());
            extraMap.put("bigArea", area.getBigArea());
            // 单个树数据构建
            TreeNode<String> treeNode = new TreeNode<String>()
                    .setId(String.valueOf(area.getId())) // 主键
                    .setParentId(String.valueOf(area.getReid())) // 父节点ID
                    .setName(area.getName()) // 省份名称
                    .setWeight(area.getSortOrder()) //权重,排序
                    .setExtra(extraMap); // 扩展字段
            return treeNode;
        }).collect(Collectors.toList());

        // 配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名(修改默认名称)
        treeNodeConfig.setWeightKey("sortOrder");
        treeNodeConfig.setChildrenKey("childrenNode");
        // 最大递归深度
        treeNodeConfig.setDeep(1);

        //转换器
        List<Tree<String>> treeNodes = TreeUtil.build(treeNodeList, "1", treeNodeConfig,
                (treeNode, tree) -> {
                    // 给树节点赋值(还能set 父 或子节点树)
                    tree.setId(treeNode.getId());
                    tree.setParentId(treeNode.getParentId());
                    tree.setWeight(treeNode.getWeight());
                    tree.setName(treeNode.getName());
                    // 扩展属性值赋值
                    // treeNode.getExtra().getOrDefault("domain", null) 是获取上面Map放进去的值,没有就是 null
                    tree.putExtra("domain", treeNode.getExtra().getOrDefault("domain", null));
                    tree.putExtra("isOpen", treeNode.getExtra().getOrDefault("isOpen", null));
                    tree.putExtra("bigArea", treeNode.getExtra().getOrDefault("bigArea", null));
                });
        return JSONUtil.parse(treeNodes);
    }*/

    public static void main(String[] args) {
        // 构建node列表
        List<TreeNode<String>> nodeList = CollUtil.newArrayList();

        /*nodeList.add(new TreeNode<>("1", "0", "系统管理", 5));
        nodeList.add(new TreeNode<>("11", "1", "用户管理", 222222));
        nodeList.add(new TreeNode<>("111", "11", "用户添加", 0));
        nodeList.add(new TreeNode<>("2", "0", "店铺管理", 1));
        nodeList.add(new TreeNode<>("21", "2", "商品管理", 44));
        nodeList.add(new TreeNode<>("221", "2", "商品管理2", 2));*/

        nodeList.add(new TreeNode<>("1", "0", "总公司", 5));
        nodeList.add(new TreeNode<>("11", "1", "用户管理", 222222));
        nodeList.add(new TreeNode<>("111", "11", "用户添加", 0));
        nodeList.add(new TreeNode<>("2", "1", "店铺管理", 1));
        nodeList.add(new TreeNode<>("21", "2", "商品管理", 44));
        nodeList.add(new TreeNode<>("221", "2", "商品管理2", 2));

        // 0表示最顶层的id是0
        List<Tree<String>> treeList = TreeUtil.build(nodeList, "0");

        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名 都要默认值的
        treeNodeConfig.setWeightKey("order");
        treeNodeConfig.setIdKey("rid");
        // 最大递归深度
        treeNodeConfig.setDeep(3);

        //转换器
        List<Tree<String>> treeNodes = TreeUtil.build(nodeList, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId());
                    tree.setParentId(treeNode.getParentId());
                    tree.setWeight(treeNode.getWeight());
                    tree.setName(treeNode.getName());
                    // 扩展属性 ...
                    tree.putExtra("extraField", 666);
                    tree.putExtra("other", new Object());
                });
        System.out.println(JSONUtil.parse(treeNodes));

    }

}

测试:

[{
	"childrenNode": [
	{
		"childrenNode": [{
			"parentId": "3",
			"name": "E",
			"id": "5",
			"text": "555",
			"createDate": 1638796839374
		}],
		"parentId": "1",
		"name": "C",
		"id": "3",
		"text": "333",
		"createDate": 1638796839374
	},
	{
		"childrenNode": [{
			"parentId": "4",
			"name": "F",
			"id": "6",
			"text": "666",
			"createDate": 1638796839374
		}],
		"parentId": "1",
		"name": "D",
		"id": "4",
		"text": "444",
		"createDate": 1638796839374
	}],
	"parentId": "0",
	"name": "A",
	"id": "1",
	"text": "111",
	"createDate": 1638796839374
},
{
	"parentId": "0",
	"name": "B",
	"id": "2",
	"text": "22",
	"createDate": 1638796839374
}]
[{
	"other": "java.lang.Object@368102c8",
	"extraField": 666,
	"rid": "1",
	"parentId": "0",
	"children": [{
		"other": "java.lang.Object@6996db8",
		"extraField": 666,
		"rid": "2",
		"parentId": "1",
		"children": [{
			"other": "java.lang.Object@1963006a",
			"extraField": 666,
			"rid": "221",
			"parentId": "2",
			"name": "商品管理2",
			"order": 2
		},
		{
			"other": "java.lang.Object@7fbe847c",
			"extraField": 666,
			"rid": "21",
			"parentId": "2",
			"name": "商品管理",
			"order": 44
		}],
		"name": "店铺管理",
		"order": 1
	},
	{
		"other": "java.lang.Object@41975e01",
		"extraField": 666,
		"rid": "11",
		"parentId": "1",
		"children": [{
			"other": "java.lang.Object@c2e1f26",
			"extraField": 666,
			"rid": "111",
			"parentId": "11",
			"name": "用户添加",
			"order": 0
		}],
		"name": "用户管理",
		"order": 222222
	}],
	"name": "总公司",
	"order": 5
}]

参考:

JAVA使用hutool工具实现查询树结构数据(省市区)

@PostMapping("/getTree")
    public Object getTree() {
        // 查询数据
        List<LxhpArea> areaList = areaService.list();
        // 构建的整个树数据
        List<TreeNode<String>> treeNodeList = areaList.stream().map(area -> {
            // 扩展字段赋值,下面要取这里的值
            Map<String, Object> extraMap = new HashMap<>();
            extraMap.put("domain", area.getDomain());
            extraMap.put("isOpen", area.getIsOpen());
            extraMap.put("bigArea", area.getBigArea());
            // 单个树数据构建
            TreeNode<String> treeNode = new TreeNode<String>()
                    .setId(String.valueOf(area.getId())) // 主键
                    .setParentId(String.valueOf(area.getReid())) // 父节点ID
                    .setName(area.getName()) // 省份名称
                    .setWeight(area.getSortOrder()) //权重,排序
                    .setExtra(extraMap); // 扩展字段
            return treeNode;
        }).collect(Collectors.toList());
 
        // 配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名(修改默认名称)
        treeNodeConfig.setWeightKey("sortOrder");
        treeNodeConfig.setChildrenKey("childrenNode");
        // 最大递归深度
        treeNodeConfig.setDeep(1);
 
        //转换器
        List<Tree<String>> treeNodes = TreeUtil.build(treeNodeList, "1", treeNodeConfig,
                (treeNode, tree) -> {
                    // 给树节点赋值(还能set 父 或子节点树)
                    tree.setId(treeNode.getId());
                    tree.setParentId(treeNode.getParentId());
                    tree.setWeight(treeNode.getWeight());
                    tree.setName(treeNode.getName());
                    // 扩展属性值赋值
                    // treeNode.getExtra().getOrDefault("domain", null) 是获取上面Map放进去的值,没有就是 null
                    tree.putExtra("domain", treeNode.getExtra().getOrDefault("domain", null));
                    tree.putExtra("isOpen", treeNode.getExtra().getOrDefault("isOpen", null));
                    tree.putExtra("bigArea", treeNode.getExtra().getOrDefault("bigArea", null));
                });
        return JSONUtil.parse(treeNodes);
    }


CREATE TABLE `lxhp_area` (
  `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `reid` smallint(5) unsigned NOT NULL DEFAULT '0',
  `name` varchar(120) NOT NULL DEFAULT '',
  `sort_order` smallint(5) unsigned NOT NULL DEFAULT '0',
  `is_open` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `domain` varchar(10) NOT NULL,
  `big_area` int(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3433 DEFAULT CHARSET=utf8;

Hutool 树形结构解析-KuangStudy-文章

使用HutoolUtil工具包之树结构工具TreeUtil 快速处理数据树形结构数据,很好很强大!_小米吃辣椒的博客-优快云博客

树结构工具-TreeUtil - Hutool 帮助文档 - 文江博客


学习hutool源码TreeUtil.build()得到了什么_www.小白-优快云博客_treeutil.build

自定义List转化Tree 工具类 Hutool TreeUtil工具类_DG_DH168的博客-优快云博客

TreeUtil 数据库菜单生成无限级树形结构_你可路过我的倾城时光、-优快云博客

java TreeUtil菜单递归工具类_男人要霸气的博客-优快云博客

TreeUtil 基本用法 便捷构建树形结构_水脏的博客-优快云博客

java使用Hutool TreeUtil工具实现树形菜单,简单配置即可_代号:猿a的博客-优快云博客

Hutool 使用TreeUtil工具解决树形结构_GideonYeung的博客-优快云博客

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZHOU_VIP

您的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值