根据根节点和子节点构造树形结构

package com.cyc.basic.test.list;

import com.alibaba.fastjson.JSON;
import lombok.Data;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @description: 遍历构造树形结构{根节点, 子节点}
 * @version 1.0
 * @author cyc
 * @date 2022/3/11 15:53
 */
public class ParentChildListTest {

    public static void main(String[] args) {
        //模拟从数据库查询出来
        List<Menu> menus = Arrays.asList(
                new Menu(1, "根节点", 0),
                new Menu(2, "父节点1", 1),
                new Menu(3, "子节点1.1", 2),
                new Menu(4, "子节点1.2", 2),
                new Menu(5, "子节点1.3", 2),
                new Menu(6, "父节点2", 1),
                new Menu(7, "子节点2.1", 6),
                new Menu(8, "子节点2.2", 6),
                new Menu(9, "子子节点2.2.1", 7),
                new Menu(10, "子子节点2.2.2", 7),
                new Menu(11, "父节点3", 1),
                new Menu(12, "子节点3.1", 11)
        );

        //获取父节点-方式1
        List<Menu> collect = menus.stream().filter(m -> m.getParentId() == 0).map(
                menu -> {
                    menu.setChildList(getChildrens(menu, menus));
                    return menu;
                }
        ).collect(Collectors.toList());

        //获取父节点-方式2, 使用peek函数, peek 对每个元素执行操作并返回一个新的 Stream
        List<Menu> collect2 = menus.stream().filter(menu -> menu.getParentId() == 0).peek(
                menu -> menu.setChildList(getChildrens(menu, menus))
        ).collect(Collectors.toList());

        System.out.println("-------转json输出结果-------");
        System.out.println(JSON.toJSON(collect));
    }

    /**
     * 递归查询子节点
     * @param root  根节点
     * @param all   所有节点
     * @return 根节点信息
     */
    private static List<Menu> getChildrens(Menu root, List<Menu> all) {
        List<Menu> children = all.stream().filter(menu -> Objects.equals(menu.getParentId(), root.getId()))
                .map(menu -> {
                            // 此时的menu作为父节点, 继续从所有节点中查询其子节点
                            menu.setChildList(getChildrens(menu, all));
                            return menu;
                        }
                ).collect(Collectors.toList());
        return children;
    }
}


@Data
class Menu {
    /**
     * id
     */
    public Integer id;
    /**
     * 名称
     */
    public String name;
    /**
     * 父id ,根节点为0
     */
    public Integer parentId;
    /**
     * 子节点信息
     */
    public List<Menu> childList;


    public Menu(Integer id, String name, Integer parentId) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
    }

}

输出结果

[{
	"name": "根节点",
	"childList": [{
		"name": "父节点1",
		"childList": [{
			"name": "子节点1.1",
			"childList": [],
			"id": 3,
			"parentId": 2
		}, {
			"name": "子节点1.2",
			"childList": [],
			"id": 4,
			"parentId": 2
		}, {
			"name": "子节点1.3",
			"childList": [],
			"id": 5,
			"parentId": 2
		}],
		"id": 2,
		"parentId": 1
	}, {
		"name": "父节点2",
		"childList": [{
			"name": "子节点2.1",
			"childList": [{
				"name": "子子节点2.2.1",
				"childList": [],
				"id": 9,
				"parentId": 7
			}, {
				"name": "子子节点2.2.2",
				"childList": [],
				"id": 10,
				"parentId": 7
			}],
			"id": 7,
			"parentId": 6
		}, {
			"name": "子节点2.2",
			"childList": [],
			"id": 8,
			"parentId": 6
		}],
		"id": 6,
		"parentId": 1
	}, {
		"name": "父节点3",
		"childList": [{
			"name": "子节点3.1",
			"childList": [],
			"id": 12,
			"parentId": 11
		}],
		"id": 11,
		"parentId": 1
	}],
	"id": 1,
	"parentId": 0
}]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

意田天

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

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

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

打赏作者

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

抵扣说明:

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

余额充值