Java组装树的几种方式

package com.example.demo.test;

import com.alibaba.fastjson.JSON;
import lombok.Data;
import org.springframework.util.CollectionUtils;

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

public class Demo {
private static int num = 0;
@Data
public static class DemoEntity {
private Integer id = num + 1;
private Integer pId;
private String name = "name" + (num + 1);
private List<DemoEntity> c = new ArrayList<>();
public DemoEntity() {
}
public DemoEntity(int i) {
pId = id - 1;
}

public DemoEntity(DemoEntity demoEntity) {
id = demoEntity.getId();
pId = demoEntity.getPId();
name = demoEntity.getName();
c = demoEntity.getC();
}
}

private static List<DemoEntity> getData(){
List<DemoEntity> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add(new DemoEntity(1));
num++;
}
return list;
}

// 直接赋值(不会产生死循环)
public static void main(String[] args) {
List<DemoEntity> data = getData();
System.out.println(JSON.toJSONString(data));
//构造返回对象
List<DemoEntity> demoTree = new ArrayList<>();
//组装
if (!CollectionUtils.isEmpty(data)) {
demoTree = data.stream().filter(j -> 0 == j.getPId()).collect(Collectors.toList());
List<DemoEntity> treeChildren = data.stream().filter(j -> 0 != j.getPId()).collect(Collectors.toList());
treeChildren.forEach(organizationalTree -> treeChildren.forEach(ot -> {
if (organizationalTree.getId().equals(ot.getPId())) {
organizationalTree.getC().add(ot);
}
}));
demoTree.forEach(demoEntity -> {
List<DemoEntity> collect = treeChildren.stream().filter(t ->
demoEntity.getId().equals(t.getPId())).collect(Collectors.toList());
demoEntity.setC(collect);
});
}
System.out.println(JSON.toJSONString(demoTree));
}

// 递归(有可能产生死循环)
public static void main(String[] args) {
List<DemoEntity> data = getData();
// 初始数据打印
System.out.println(JSON.toJSONString(data));
// 构造返回对象
List<DemoEntity> demoTree;
// 组装
// 找到根节点,0为根节点
demoTree = data.stream().filter(item -> 0 == item.getPId()).collect(Collectors.toList());
for (DemoEntity parent : demoTree) {
recursionToTree(parent, data);
}
// 树结构打印
System.out.println(JSON.toJSONString(demoTree));
}

public static void recursionToTree(DemoEntity parent, List<DemoEntity> permissions) {
if (CollectionUtils.isEmpty(permissions) || parent == null) {
return;
}
List<DemoEntity> children = permissions.stream()
.filter(item -> parent.getId().equals(item.getPId()))
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(children)) {
return;
}
parent.setC(children);
for (DemoEntity child : children) {
recursionToTree(child, permissions);
}
}

// stream 递归
public static void main(String[] args) {
List<DemoEntity> data = getData();
// 初始数据打印
System.out.println(JSON.toJSONString(data));
// 找到根节点,0为根节点 组装
data = streamToTree(0, data);
// 树结构打印
System.out.println(JSON.toJSONString(data));
}

public static List<DemoEntity> streamToTree(Integer root, List<DemoEntity> permissions) {
return permissions.stream().filter(e -> Objects.equals(root, e.getPId()))
.peek(e -> e.setC(streamToTree(e.getId(), permissions)))
.collect(Collectors.toList());
}

// stream 分组组装
public static void main(String[] args) {
List<DemoEntity> data = getData();
// 初始数据打印
System.out.println(JSON.toJSONString(data));
// 找到根节点,0为根节点 组装
data = streamToTree(0, data);
// 树结构打印
System.out.println(JSON.toJSONString(data));
}

public static List<DemoEntity> streamToTree(Integer root, List<DemoEntity> permissions) {
//非根路径集合根据pid分组
Map<Integer, List<DemoEntity>> pidGroupByMap = permissions.stream()
.filter(x -> !Objects.equals(root, x.getPId()))
.collect(Collectors.groupingBy(DemoEntity::getPId));
//设置子节点
permissions.forEach(x -> x.setC(pidGroupByMap.get(x.getId())));
//只保留根节点
return permissions.stream().filter(x -> Objects.equals(root, x.getPId()))
.collect(Collectors.toList());
}


}

__EOF__

本文作者东峰叵.com
本文链接https://www.cnblogs.com/databank/p/16616866.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   东峰叵,com  阅读(200)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示