前言
在日常开发中,必不可少的就是树形结构。
有的时候可以使用Mybatis的ResultMap进行转化,有的时候需要进行Java进行手动转化为树结构。
这里分享一个JDK8新特性Stream来实现List到树形结构的转化。
大家根据需要,可以拿去用,或者在此基础上进行深层次的封装。
实体类MenuNode
package com.itjing.treemenu;
import lombok.*;
import java.util.List;
/**
* @author lijing
* @date 2022年05月31日 20:23
* @description 菜单节点
*/
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class MenuNode implements Comparable<MenuNode> {
private String id;
private String menuCode;
private String menuName;
private String pid;
private List<MenuNode> children;
public MenuNode(String id, String menuCode, String menuName, String pid) {
this.id = id;
this.menuCode = menuCode;
this.menuName = menuName;
this.pid = pid;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof MenuNode) {
MenuNode node = (MenuNode) obj;
return this.id.equals(node.getId());
} else {
return super.equals(obj);
}
}
@Override
public int compareTo(MenuNode o) {
return this.getMenuCode().compareTo(o.getMenuCode());
}
}
List转树形工具类
package com.itjing.treemenu;
import com.alibaba.fastjson.JSON;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author lijing
* @date 2022年05月31日 20:30
* @description 树形菜单工具类
*/
public class TreeMenuUtil {
/**
* 生成菜单树
*
* @param menuNodes
* @return
*/
private static List<MenuNode> listWithTree(List<MenuNode> menuNodes) {
// 组装成父子的树形结构
List<MenuNode> level1Menus = menuNodes.stream()
// 找到一级菜单
.filter(node -> StringUtils.isEmpty(node.getPid()))
.map(node -> {
// 从所有菜单中找menu的子菜单
node.setChildren(getChildrens(node, menuNodes));
return node;
})
// 按照menuCode排序并处理为空情况,nullsLast是值将空值放最后,nullsFirst同理
.sorted(Comparator.comparing(MenuNode::getMenuCode, Comparator.nullsLast(String::compareTo)))
.collect(Collectors.toList());
return level1Menus;
}
/**
* 递归查找所有菜单的子菜单
*
* @param root
* @param all
* @return
*/
public static List<MenuNode> getChildrens(MenuNode root, List<MenuNode> all) {
List<MenuNode> childrens = all.stream()
.filter(node -> Objects.equals(node.getPid(), root.getId()))
.map(node -> {
// 找到子菜单
node.setChildren(getChildrens(node, all));
return node;
})
// 排序,可以自行定义排序规则
// 按照menuCode排序并处理为空情况,nullsLast是值将空值放最后,nullsFirst同理
.sorted(Comparator.comparing(MenuNode::getMenuCode, Comparator.nullsLast(String::compareTo)))
.collect(Collectors.toList());
return childrens;
}
}
测试
public static void main(String[] args) {
MenuNode node1 = new MenuNode("1", "1", "江苏省", "");
MenuNode node2 = new MenuNode("2", "3", "连云港市", "1");
MenuNode node3 = new MenuNode("3", "1", "灌云县", "2");
MenuNode node4 = new MenuNode("4", "2", "苏州市", "1");
MenuNode node5 = new MenuNode("5", "4", "无锡市", "1");
MenuNode node6 = new MenuNode("6", "5", "盐城市", "1");
MenuNode node7 = new MenuNode("7", "6", "淮安市", "1");
List<MenuNode> list = new ArrayList<>();
list.add(node1);
list.add(node2);
list.add(node3);
list.add(node4);
list.add(node5);
list.add(node6);
list.add(node7);
List<MenuNode> menu = listWithTree(list);
System.out.println(JSON.toJSONString(menu));
}
结果展示:
[
{
"children": [
{
"children": [],
"id": "4",
"menuCode": "2",
"menuName": "苏州市",
"pid": "1"
},
{
"children": [
{
"children": [],
"id": "3",
"menuCode": "1",
"menuName": "灌云县",
"pid": "2"
}
],
"id": "2",
"menuCode": "3",
"menuName": "连云港市",
"pid": "1"
},
{
"children": [],
"id": "5",
"menuCode": "4",
"menuName": "无锡市",
"pid": "1"
},
{
"children": [],
"id": "6",
"menuCode": "5",
"menuName": "盐城市",
"pid": "1"
},
{
"children": [],
"id": "7",
"menuCode": "6",
"menuName": "淮安市",
"pid": "1"
}
],
"id": "1",
"menuCode": "1",
"menuName": "江苏省",
"pid": ""
}
]
原文始发于微信公众号(程序员阿晶):Java8使用Stream将List集合转化为树形结构
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/19595.html