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());
}


}
posted @ 2022-08-23 16:41  东峰叵,com  阅读(204)  评论(0)    收藏  举报