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

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
}]
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JavaScript中,可以使用对象或数组来构造树形结构数据。其中,对象表示节点,通过属性来表示节点的值和子节点。数组表示节点的集合,通过索引来表示节点的位置。 例如,可以使用以下代码构造一个树形结构的数据: ```javascript const tree = { value: 'A', children: [ { value: 'B', children: [ { value: 'D', children: [] }, { value: 'E', children: [] } ] }, { value: 'C', children: [ { value: 'F', children: [] } ] } ] }; ``` 在这个例子中,节点是'A',它有两个子节点'B'和'C'。节点'B'有两个子节点'D'和'E',节点'C'有一个子节点'F'。每个节点都有一个value属性表示节点的值,以及一个children属性表示子节点的集合。 通过这种方式,我们可以灵活地构造树形结构的数据,并且方便地进行遍历和操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【JS】数据结构之结构](https://blog.csdn.net/qq_45677671/article/details/127905453)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [JavaScript实现结构(一)](https://blog.csdn.net/qq_42198495/article/details/108014346)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

意田天

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

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

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

打赏作者

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

抵扣说明:

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

余额充值