Java8使用Stream将List集合转化为树形结构

前言

在日常开发中,必不可少的就是树形结构。

Java8使用Stream将List集合转化为树形结构

有的时候可以使用Mybatis的ResultMap进行转化,有的时候需要进行Java进行手动转化为树结构。

这里分享一个JDK8新特性Stream来实现List到树形结构的转化。

大家根据需要,可以拿去用,或者在此基础上进行深层次的封装。

Java8使用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集合转化为树形结构

原文始发于微信公众号(程序员阿晶):Java8使用Stream将List集合转化为树形结构

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/19595.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!