背景
背景不说了吧,开发中很多时候都遇得到构建一个 【树形关系】的数据场景
java
id:1
parentId:0
id:2
parentId:1
id:3
parentId:2
id:4
parentId:2
像这样:
今天封装一个工具类,专门把 List<T> 转换为 Tree<T>
正文
假设我们有一个 Person 类
java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person implements NodeOfId<Person>{
private Long id;
private Long parentId;
private String name;
private List<Person> children;
}
我们需要一个 构建树形 数据节点的 基类
java
public interface NodeOfId<T> {
Long getId();
Long getParentId();
void setChildren(List<T> children);
}
这个 基类 getId(),getPrentId() ,setChildren()都是可以更改的,根据你的类字段定义,只要能有构建出树形关系的字段就行
构建树封装工具类
java
public class TreeUtil {
/**
* 构造list为树集合
*
* @param nodes
* @param <T>
* @return
*/
public static <T extends NodeOfId<T>> List<T> buildTreeList(List<T> nodes) {
Map<Long, List<T>> groupMap = nodes.stream().collect(Collectors.groupingBy(T::getParentId));
return nodes.stream().filter(m -> m.getParentId() == 0).peek(
(m) -> m.setChildren(getChildren(m, groupMap))
).collect(Collectors.toList());
}
/**
* 递归查询子节点
*
* @param root 根节点
* @param groupMap 将所有节点根据自己的父级ID进行分组
* @return 根节点信息
*/
private static <T extends NodeOfId<T>> List<T> getChildren(T root, Map<Long, List<T>> groupMap) {
return groupMap.getOrDefault(root.getId(), new ArrayList<>()).stream().peek(
(m) -> m.setChildren(getChildren(m, groupMap))
).collect(Collectors.toList());
}
}
写个单元测试:
java
public static void test1() {
List<Person> list = new ArrayList<>();
Person person1 = new Person(1L, 0L, "A", null);
Person person2 = new Person(2L, 1L, "B", null);
Person person3 = new Person(3L, 2L, "C", null);
Person person4 = new Person(4L, 2L, "D", null);
list.add(person1);
list.add(person2);
list.add(person3);
list.add(person4);
List<Person> treeList = TreeUtil.buildTreeList(list);
System.out.println(JSON.toJSONString(treeList));
}
运行结果:
格式化看一下:
非常好用!!