1.stream递归操作
private List<DemoVO> createtree(List<Demo> datas) {
//得到父节点
return datas.stream()
.filter(m -> TargetConstants.ROOT.equalsIgnoreCase(m.getParentId()))
.map(m -> {
DemoVO vo = new DemoVO();
vo.setTaxonomyId(m.getPlatformTaxonomyId());
vo.setTaxonomyName(m.getPlatformTaxonomyName());
vo.setType(m.getType());
vo.setStatus(m.getStatus());
vo.setUpdateTime(m.getUpdateTime());
vo.setChildren(buildChildNodes(m, datas));
return vo;
})
.collect(Collectors.toList());
}
private List<DemoVO> buildChildNodes(Demo root, List<Demo> list){
return list.stream()
.filter(m -> Objects.equals(root.getPlatformTaxonomyId(), m.getParentId()))
.map(m -> {
DemoVO vo = new DemoVO();
vo.setTaxonomyId(m.getPlatformTaxonomyId());
vo.setTaxonomyName(m.getPlatformTaxonomyName());
vo.setType(m.getType());
vo.setStatus(m.getStatus());
vo.setUpdateTime(m.getUpdateTime());
vo.setChildren(buildChildNodes(m, list));
return vo;
}).collect(Collectors.toList());
}
关键点
-
递归算法:
- 通过
buildChildNodes
方法递归构建子树,直到没有子节点为止。
- 通过
-
数据关联:
- 通过
parentId
和platformTaxonomyId
的匹配建立父子关系。
- 通过
-
不变性:
- 假设 Demo是只读的,每次递归创建新的 Demo
VO
对象。
- 假设 Demo是只读的,每次递归创建新的 Demo
2.使用栈或队列的迭代方式可避免递归深度问题(适合超深层级数据):
private List<DemoVO> createTreeIterative(List<Demo> datas) {
Map<String, DemoVO> nodeMap = new HashMap<>();
Map<String, List<Demo>> parentToChildren = datas.stream()
.collect(Collectors.groupingBy(Demo::getParentId));
// 所有节点预创建
datas.forEach(data -> {
DemoVO vo = new DemoVO();
vo.setTaxonomyId(data.getPlatformTaxonomyId());
vo.setTaxonomyName(data.getPlatformTaxonomyName());
nodeMap.put(data.getPlatformTaxonomyId(), vo);
});
// 构建父子关系
nodeMap.values().forEach(vo -> {
List<Demo> childrenData = parentToChildren.get(vo.getTaxonomyId());
if (childrenData != null) {
vo.setChildren(childrenData.stream()
.map(child -> nodeMap.get(child.getPlatformTaxonomyId()))
.collect(Collectors.toList()));
}
});
// 返回根节点
return parentToChildren.getOrDefault(TargetConstants.ROOT, Collections.emptyList())
.stream()
.map(root -> nodeMap.get(root.getPlatformTaxonomyId()))
.collect(Collectors.toList());
}