多平台统一管理软件接口,如何实现多平台统一管理软件接口
799
2022-11-20
java之TreeUtils生成一切对象树形结构案例
项目中经常会遇到各种需要以树形结构展示的功能,比较常见的,如菜单树,分类树,部门树等等,如果为每种类型都遍历递归生成树形结构返回给前端,显得有些冗余且麻烦,并且其实逻辑都是一致的,只是遍历的对象不同而已,故其实可以通过面向接口思维,来实现这种通用工具类的实现。
TreeNode用来表示每个树节点的抽象,即需要生成树的对象需要实现此接口。
/**
* 树节点父类,所有需要使用{@linkplain TreeUtils}工具类形成树形结构等操作的节点都需要实现该接口
*
* @param
*/
public interface TreeNode
/**
* 获取节点id
*
* @return 树节点id
*/
T id();
/**
* 获取该节点的父节点id
*
* @return 父节点id
*/
T parentId();
/**
* 是否是根节点
*
* @return true:根节点
*/
boolean root();
/**
* 设置节点的子节点列表
*
* @param children 子节点
*/
void setChildren(List extends TreeNode
/**
* 获取所有子节点
*
* @return 子节点列表
*/
List extends TreeNode
}
TreeUtils用来生成树形结构,以及获取所有叶子节点等操作
/**
* 树形结构工具类
*
* @author meilin.huang
* @version 1.0
* @date 2019-08-24 1:57 下午
*/
public class TreeUtils {
/**
* 根据所有树节点列表,生成含有所有树形结构的列表
*
* @param nodes 树形节点列表
* @param
* @return 树形结构列表
*/
public static
List
for (Iterator
T node = ite.next();
if (node.root()) {
roots.add(node);
// 从所有节点列表中删除该节点,以免后续重复遍历该节点
ite.remove();
}
}
roots.forEach(r -> {
setChildren(r, nodes);
});
return roots;
}
/**
* 从所有节点列表中查找并设置parent的所有子节点
*
* @param parent 父节点
* @param nodes 所有树节点列表
*/
@SuppressWarnings("all")
public static
List
Object parentId = parent.id();
for (Iterator
T node = ite.next();
if (Objects.equals(node.parentId(), parentId)) {
children.add(node);
// 从所有节点列表中删除该节点,以免后续重复遍历该节点
ite.remove();
}
}
// 如果孩子为空,则直接返回,否则继续递归设置孩子的孩子
if (children.isEmpty()) {
return;
}
parent.setChildren(children);
children.forEach(m -> {
// 递归设置子节点
setChildren(m, nodes);
});
}
/**
* 获取指定树节点下的所有叶子节点
*
* @param parent 父节点
* @param
* @return 叶子节点
*/
public static
List
fillLeaf(parent, leafs);
return leafs;
}
/**
* 将parent的所有叶子节点填充至leafs列表中
*
* @param parent 父节点
* @param leafs 叶子节点列表
* @param
*/
@SuppressWarnings("all")
public static
List
// 如果节点没有子节点则说明为叶子节点
if (CollectionUtils.isEmpty(children)) {
leafs.add(parent);
return;
}
// 递归调用子节点,查找叶子节点
for (T child : children) {
fillLeaf(child, leafs);
}
}
}
具体使用方式之声明树节点对象
@Getter
@Setter
public class ResourceListVO implements TreeNode
private Long id;
private Long pid;
private Integer type;
private String name;
private String icon;
private String code;
private Integer status;
private List
@Override
public Long id() {
return this.id;
}
@Override
public Long parentId() {
return this.pid;
}
@Override
public boolean root() {
return Objects.equals(this.pid, 0L);
}
@Override
public void setChildren(List children) {
this.children = children;
}
}
具体使用方式之调用
/**
* 获取账号的资源树
*/
public List
return TreeUtils.generateTrees(BeanUtils.copyProperties(mapper.selectByAccountId(userId), ResourceListVO.class));
}
通过使用TreeUtils工具可以统一方便地生成一切对象的树CvafJD形结构以及其他一些对树的操作,避免对每个对象都用特定代码生成。使用起来就是几个字简洁方便爽歪歪biu特否。
补充知识:TreeUtil 数据库菜单生成无限级树形结构
1、项目需求:
从数据库从加载所有的菜单出来,菜单中有
id,parentId,name字段
希望能有一个工具帮我进行树形结构重组;
实例类:
package com.lming.chcservice.util;
import lombok.Data;
import java.util.List;
@Data
public class TreeNode {
/**
* 节点id
*/
private String id;
/**
* 父节点 默认0为根节点
*/
private String parentId;
/**
* 节点名称
*/
private String name;
/**
* 是否有子节点
*/
private boolean hasChild;
public TreeNode(String id, String parentId, String name) {
this.id = id;
this.parentId = parentId;
this.name = name;
}
}
工具类:
package com.lming.chcservice.util;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 树形结构工具类
*
* 将一组list对象转成树形结构
* 该list需符合设定的字段类型
*
*/
public class TreeUtil {
public static Map
public List
public List
public List
this.menuCommon = menu;
for (TreeNode treeNode : menu) {
Map
if(treeNode.getParentId().equals("0")){
setTreeMap(mapArr,treeNode);
list.add(mapArr);
}
}
return list;
}
public List> menuChild(String id){
List
for(TreeNode a:menuCommon){
Map
if(a.getParentId() .equals(id)){
setTreeMap(childArray,a);
lists.add(childArray);
}
}
return lists;
}
private void setTreeMap(Map<String,Object> mapArr,TreeNode treeNode){
mapArr.put("id", treeNode.getId());
mapArr.put("name", treeNode.getName());
mapArr.put("parentId", treeNode.getParentId());
List> childrens = menuChild(treeNode.getId());
if(childrens.size()>0){
mapArr.put("hasChild",true);
}
else{
mapArr.put("hasChildren",false);
}
mapArr.put("childrens", menuChild(treeNode.getId()));
}
public static void main(String[] args){
List
TreeNode treeNode1 = new TreeNode("1","0","首页");
TreeNode treeNode2 = new TreeNode("2","0","订单");
TreeNode treeNode3 = new TreeNode("3","1","预约");
TreeNode treeNode4 = new TreeNode("4","2","捐献");
TreeNode treeNode5 = new TreeNode("5","4","我的订单");
TreeNode treeNode6 = new TreeNode("6","5","个人中心");
TreeNode treeNode7 = new TreeNode("7","6","个人中心2");
TreeNode treeNode8 = new TreeNode("8","99","个人中心3");
treeNodeList.add(treeNode1);
treeNodeList.add(treeNode6);
treeNodeList.add(treeNode5);
treeNodeList.add(treeNode3);
treeNodeList.add(treeNode4);
treeNodeList.add(treeNode2);
treeNodeList.add(treeNode7);
treeNodeList.add(treeNode8);
TreeUtil treeUtil = new TreeUtil();
System.out.print(jsonUtil.toJson(treeUtil.treeMenu(treeNodeList)));
}
}
测试结果:
[
{
"id": "1",
"name": "首页",
"parentId": "0",
"hasChild": true,
"childrens": [
{
"id": "3",
"name": "预约",
"parentId": "1",
"hasChildren": false,
"childrens": []
}
]
},
{
"id": "2",
"name": "订单",
"parentId": "0",
"hasChild": true,
"childrens": [
{
"id": "4",
"name": "捐献",
"parentId": "2",
"hasChild": true,
"childrens": [
{
"id": "5",
"name": "我的订单",
"parentId": "4",
"hasChild": true,
"childrens": [
{
"id": "6",
"name": "个人中心",
"parentId": "5",
"hasChild": true,
"childrens": [
{
"id": "7",
"name": "个人中心2",
"parentId": "6",
"hasChildren": false,
"childrens": []
}
]
}
]
}
]
}
]
}
]
实力类不一致怎么办? 自己写一个实体转换类,将类的对象属性转换成上面的实体类,然后在调用,当然最快的方式直接修改实体类即可用。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~