list转tree简单循环实现
前言
我们在平时开发中,难免会遇到一些list转tree的情况,例如省市区及区下面的一些区域,就需要用到树的形式,而我们的原始数据为了存储方便一般拿出来都是list的形式,这时候就需要转换
构造对象
这里的pId表示上级节点的id,设定顶级节点的pId = 0
@Data
public class TreeNode {
private Long id;
private Long pId;
private String name;
private List<TreeNode> child;
}
分析逻辑
入参是一个没有chid的List< TreeNode>,包含所有层级的节点
- 先把list按照pid分组,value则是pid对应的child
- 构造循环的条件:当没有下级节点的时候
- 循环内封装数据
实现方法
public static List<TreeNode> buildTree(List<TreeNode> list) {
// 数据校验
if (CollectionUtils.isEmpty(list)) {
return Collections.emptyList();
}
// 过滤掉null并按照pId分组
Map<Long, List<TreeNode>> map = list.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(TreeNode::getPId));
// 再校验一次
if (MapUtils.isEmpty(map)) {
return Collections.emptyList();
}
// 获取一级节点,树的根节点
List<TreeNode> res = map.get(0L);
// 父级节点
List<TreeNode> parent = res;
while (true) {
List<TreeNode> temp = new ArrayList<>();
// 遍历父级节点
for (TreeNode treeNode : parent) {
Long pId = treeNode.getId();
// 封装child
if (map.containsKey(pId)) {
List<TreeNode> child = map.get(pId);
treeNode.setChild(child);
temp.addAll(child);
}
}
// 直到没有子节点
if (CollectionUtils.isEmpty(temp)) {
break;
}
// 继续下一次循环
parent = temp;
}
return res;
}