开发中如何获取一个树结构是非常常见的需求,本示例演示一下该功能如何实现。

1、数据准备(mysql)

CREATE TABLE `dept` (
`dept_id` int NOT NULL AUTO_INCREMENT COMMENT 'id值',
`parent_id` int DEFAULT NULL COMMENT '上级部门',
`dept_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '名称',
`sort` int DEFAULT NULL COMMENT '排序',
PRIMARY KEY (`dept_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=212 DEFAULT CHARSET=utf8; INSERT INTO `dept` VALUES ('1', '0', '成都总公司', '1');
INSERT INTO `dept` VALUES ('2', '0', '宜宾分公司', '2');
INSERT INTO `dept` VALUES ('10', '1', '研发部门', '1');
INSERT INTO `dept` VALUES ('11', '1', '市场部门', '2');
INSERT INTO `dept` VALUES ('12', '1', '运维部门', '3');
INSERT INTO `dept` VALUES ('21', '2', '营销部门', '1');
INSERT INTO `dept` VALUES ('22', '2', '运维部门', '2');
INSERT INTO `dept` VALUES ('23', '2', '公关部门', '3');
INSERT INTO `dept` VALUES ('210', '21', '小组1', '2');
INSERT INTO `dept` VALUES ('211', '21', '小组2', '1');

2、工程结构

核心的类就是如下标红的类

3、核心源码

package com.example.demo.unit;

import java.util.List;
//实现Comparable接口,重写其CompareTo方法
public class Tree<T> implements Comparable {
String id;
String name;
String parentId;
List<T> children; private Integer order; 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 String getParentId() {
return parentId;
} public void setParentId(String parentId) {
this.parentId = parentId;
} public List<T> getChildren() {
return children;
} public void setChildren(List<T> children) {
this.children = children;
} /**
* @param order
* the order to set
*/
public void setOrder(Integer order) {
this.order = order;
} /**
* @return the order
*/
public Integer getOrder() {
return order;
} //定义排序规则
@Override
public int compareTo(Object o) {
Tree tree =(Tree) o;
return this.getOrder().compareTo(tree.getOrder()); //这里定义你排序的规则。
} @Override
public String toString() {
return "Tree{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", parentId='" + parentId + '\'' +
", children=" + children +
'}';
} }
package com.example.demo.unit;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors; public class TreeUtils {
//构建部门树方法 没有排序
public static List buildTreeNoSort(List<Tree> trees, String parentId) {
//将每条数据的子节点添加进去
for (Tree tree : trees) {
for (Tree tree1 : trees) {
if (tree1.getParentId().equals(tree.getId())) {
if (tree.getChildren() == null) {
tree.setChildren(new ArrayList());
}
tree.getChildren().add(tree1);
}
}
}
System.out.println(trees);
//把父节点是根节点的数据过滤出来就是最后的树
return trees.stream().filter(tree -> tree.getParentId().equals(parentId)).collect(Collectors.toList());
} //构建部门树方法 有排序
public static List buildTreeSort(List<Tree> trees, String parentId) {
//将每条数据的子节点添加进去
for (Tree tree : trees) {
for (Tree tree1 : trees) {
if (tree1.getParentId().equals(tree.getId())) {
if (tree.getChildren() == null) {
tree.setChildren(new ArrayList());
}
tree.getChildren().add(tree1);
//排序
Collections.sort(tree.getChildren());
}
}
}
System.out.println(trees);
//把父节点是根节点的数据过滤出来就是最后的树
return trees.stream().filter(tree -> tree.getParentId().equals(parentId)).collect(Collectors.toList());
}
}
package com.example.demo.controller;

import com.example.demo.domain.Dept;
import com.example.demo.mapper.DeptMapper;
import com.example.demo.unit.Tree;
import com.example.demo.unit.TreeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList;
import java.util.List; @RestController
@RequestMapping("/hello")
public class HelloController { @Autowired
private DeptMapper deptMapper; //获取部门树,没有排序
@GetMapping("/getTreeNoSort")
@ResponseBody
public List<Tree> getTreeNoSort() { List<Dept> list = deptMapper.selectList(null); List<Tree> treeList = new ArrayList<Tree>(); //这样写避免在循环里写Tree tree = new Tree();
Tree tree = null;
for(int i=0;i<list.size();i++){
Dept dept = list.get(i);
//这种写法 仅在内存中保存一份对该对象的引用,而不像Tree tree = new Tree(); 写在循环里会在内存中产生大量的对象引用,浪费大量的内存空间,而且增大了垃圾回收的负荷。
tree = new Tree();
tree.setId(dept.getDeptId());
tree.setName(dept.getDeptName());
tree.setParentId(dept.getParentId());
treeList.add(tree);
}
List<Tree> treeDemo = TreeUtils.buildTreeNoSort(treeList,"0");
return treeDemo;
} //获取部门树有排序功能
@GetMapping("/getTreeSort")
@ResponseBody
public List<Tree> getTreeSort() { List<Dept> list = deptMapper.selectList(null); List<Tree> treeList = new ArrayList<Tree>();
Tree tree = null;
for(int i=0;i<list.size();i++){
Dept dept = list.get(i);
tree = new Tree();
tree.setId(dept.getDeptId());
tree.setName(dept.getDeptName());
tree.setParentId(dept.getParentId());
tree.setOrder(dept.getSort());
treeList.add(tree);
}
List<Tree> treeDemo = TreeUtils.buildTreeSort(treeList,"0");
return treeDemo;
}
}

4、测试

(1)测试没有排序的部门树

http://localhost:8080/hello/getTreeNoSort

[
{
"id": "1",
"name": "成都总公司",
"parentId": "0",
"children": [
{
"id": "10",
"name": "研发部门",
"parentId": "1",
"children": null,
"order": null
},
{
"id": "11",
"name": "市场部门",
"parentId": "1",
"children": null,
"order": null
},
{
"id": "12",
"name": "运维部门",
"parentId": "1",
"children": null,
"order": null
}
],
"order": null
},
{
"id": "2",
"name": "宜宾分公司",
"parentId": "0",
"children": [
{
"id": "21",
"name": "营销部门",
"parentId": "2",
"children": [
{
"id": "210",
"name": "小组1",
"parentId": "21",
"children": null,
"order": null
},
{
"id": "211",
"name": "小组2",
"parentId": "21",
"children": null,
"order": null
}
],
"order": null
},
{
"id": "22",
"name": "运维部门",
"parentId": "2",
"children": null,
"order": null
},
{
"id": "23",
"name": "公关部门",
"parentId": "2",
"children": null,
"order": null
}
],
"order": null
}
]

(2)有排序的部门树

http://localhost:8080/hello/getTreeSort

这里使用了排序算法功能,原始数据如下,小组2排在了小组1前面。

INSERT INTO `dept` VALUES ('210', '21', '小组1', '2');
INSERT INTO `dept` VALUES ('211', '21', '小组2', '1');
[
{
"id": "1",
"name": "成都总公司",
"parentId": "0",
"children": [
{
"id": "10",
"name": "研发部门",
"parentId": "1",
"children": null,
"order": 1
},
{
"id": "11",
"name": "市场部门",
"parentId": "1",
"children": null,
"order": 2
},
{
"id": "12",
"name": "运维部门",
"parentId": "1",
"children": null,
"order": 3
}
],
"order": 1
},
{
"id": "2",
"name": "宜宾分公司",
"parentId": "0",
"children": [
{
"id": "21",
"name": "营销部门",
"parentId": "2",
"children": [
{
"id": "211",
"name": "小组2",
"parentId": "21",
"children": null,
"order": 1
},
{
"id": "210",
"name": "小组1",
"parentId": "21",
"children": null,
"order": 2
}
],
"order": 1
},
{
"id": "22",
"name": "运维部门",
"parentId": "2",
"children": null,
"order": 2
},
{
"id": "23",
"name": "公关部门",
"parentId": "2",
"children": null,
"order": 3
}
],
"order": 2
}
]

java获取部门树的方法实例的更多相关文章

  1. Java获取各种常用时间方法大全

    Java获取各种常用时间方法大全 package cc.javaweb.test; Java中文网,Java获取各种时间大全 import java.text.DateFormat; import j ...

  2. (转)Java.lang.reflect.Method invoke方法 实例

    背景:今天在项目中用到Method 的invoke方法,但是并不理解,查完才知道,原来如此! import java.lang.reflect.Method; /** * Java.lang.refl ...

  3. java ----获取路径的各种方法(总结)

    Java Web开发中路径问题小结 (1) Web开发中路径的几个基本概念 假设在浏览器中访问了如下的页面,如图1所示: 那么针对这个站点的几个基本概念表述如下: 1. web站点的根目录:http: ...

  4. php 两种获取分类树的方法

    php 两种获取分类树的方法 1. /** * 获取分类树 * @param array $array 数据源 * @param int $pid 父级ID * @param int $level 分 ...

  5. 根据租户id获取部门树状结构有父子结构的数据list

    /** * 根据租户id获取部门树状结构 * @param tenantId * @return */ @GetMapping("getDeptTreeList") public ...

  6. Java 获取当前系统时间方法比较

    转载: http://blog.csdn.net/zzjjiandan/article/details/8372617 一. 获取当前系统时间和日期并格式化输出: import java.util.D ...

  7. java获取当前时间戳的方法

    获取当前时间戳 //方法 一 System.currentTimeMillis(); //方法 二 Calendar.getInstance().getTimeInMillis(); //方法 三 n ...

  8. Java获取文件大小的正确方法(转)

    Java中获取文件大小的正确方法 2014-03-28 14:03 64507人阅读 评论(9) 收藏 举报  分类: Java笔记(36)  研究成果(42)  版权声明:本文为博主原创文章,未经博 ...

  9. java 获取路径的各种方法

    (1).request.getRealPath("/");//不推荐使用获取工程的根路径 (2).request.getRealPath(request.getRequestURI ...

  10. 【转载】java 获取路径的各种方法

    转载只供个人学习参考,查看请前往原出处:http://www.cnblogs.com/guoyuqiangf8/p/3506768.html 主要方法有: (1).request.getRealPat ...

随机推荐

  1. C语言所有运算符及优先级、结合性

    C 语言所有运算符及优先级.结合性 参考:<C Primer Plus 第六版> Tip:有关优先级.结合性的表格在最后面. [1]算数运算符 '+'("加号")(二元 ...

  2. java中的try-with-resource语法

    java的世界千奇百怪...当我甩出如下代码段,不知阁下如何应对? try(A a=new A()){ 和a变量无关的业务代码块 } 没错,这就是"臭名昭著"的try-with-r ...

  3. MySQL运维11-Mycat分库分表之应用指定分片

    一.应用指定分片 此规则是在运行阶段有应用自主决定路由到那个分片,根据提供的字段,然后按照指定的规则,截取该字段的部分子字符串当做分片的依据,该分别方法比较灵活,适用于某个字段有几个特殊的字符串拼接而 ...

  4. Scrapy框架架构

    ENGINE:引擎,负责各个组件的管理. SPIDERS:各个爬虫文件类.(我们一般要写的代码就是这个). SCHEDULER:调度器,ENGINE将爬虫任务分发给该组件,由该组件调度爬虫任务. DO ...

  5. parameterType的用法

    在mybatis映射接口的配置中,有select,insert,update,delete等元素都提到了parameterType的用法,parameterType为输入参数,在配置的时候,配置相应的 ...

  6. 酷表ChatExcel -北大出品免费自动处理表格工具

    酷表ChatExcel是通过文字聊天实现Excel的交互控制的AI辅助工具,期望通过对表输入需求即可得到处理后的数据(想起来很棒),减少额外的操作,辅助相关工作人员(会计,教师等)更简单的工作.Cha ...

  7. 聊聊ChatGLM-6B部署与微调的深入理解

    ChatGLM的部署,主要是两个步骤: 在Github上下载chatglm的库文件 在Hugging Face上下载模型参数与配置文件 ChatGLM包 从Github上看ChatGLM项目文件的结构 ...

  8. 如何从零开始实现TDOA技术的 UWB 精确定位系统(3)

    ​ 这是一个系列文章<如何从零开始实现TDOA技术的 UWB 精确定位系统>第3部分. 重要提示(劝退说明): Q:做这个定位系统需要基础么?A:文章不是写给小白看的,需要有电子技术和软件 ...

  9. #11独立开发周总结|核心OKR1000元/月已达标

    核心OKR:1000元/月达成情况 算上微信上收费了200多元,核心OKR已达标 12.25-12.29本周完成事项 产品方面 本周产品上主要是在进行重构的测试,顺利上线,线上问题也比较少 运营方面 ...

  10. 用AI在本地给.NET设计几张壁纸

    AI是当今和未来非常重要的技术领域之一,它在各个行业都有广泛的应用,如医疗保健.金融.教育.制造业等.学习AI可以让你了解和掌握未来技术发展的核心,并为未来的职业发展做好准备.现在有很多开源的Mode ...