?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
?對象。
-
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());
}