关于树形数据结构遍历的一点想法
工作中经常会用到树形数据结构的遍历和返回
例如:
A implements Serializable{
/**
* 主键
*/
private String sortId;
/**
* 父级id
*/
private String parentId;
}
response:
{
"status": 0,
"msg": "加载成功!",
"data": [
{
"sortId": "sort15486394774063089",
"lastSortId": "0",
"children": [
{
"sortId": "sort20137635229450589",
"parentId": "sort15486394774063089",
"children": [
{
"sortId": "sort20137710716617553",
"parentId": "sort20137635229450589",
"children": null,
}
]
}
]
}
]
}
在这里提供一种思路
首先筛选出两个集合 父集和子集
这里假设根节点id为0
// 筛出根节点作为父集
List<A> resultList = nodeList.stream().filter(node -> "0".equals(node.getParentId()))
.collect(Collectors.toList());
// 筛出非根节点作为子集
List<A> noRootList = nodeList.stream().filter(node -> !"0".equals(node.getParentId()))
.collect(Collectors.toList());
若子集不为空,进入递归
if (noRootList.size() > 0) {
resolveChild(resultList, noRootList);
}
递归的核心是父集和子集的双循环
将符合条件的子元素放入父集
同时
子集.size()-1
父集.size()+1
// 父集循环
for (int i = 0; i < parentList.size(); i++) {
A parent = parentList.get(i);
// 子集循环
Iterator<A> iterator = childList.iterator();
while (iterator.hasNext()) {
A child = iterator.next();
if (parent.getSortId().equals(child.getParentId())) {
// 判空
List<A> templateList = new ArrayList<>();
if (parent.getChildren() != null) {
templateList = parent.getChildren();
}
// 执行追加
templateList.add(child);
parent.setChildren(templateList);
// 父集+1 子集-1
parentList.add(child);
iterator.remove();
}
}
}
在这里要注意遍历List时索引值的问题
跳出递归的条件:
// 终止递归条件:子集个数为零
while (childList.size() > 0) {
resolveChild(parentList, childList);
}
最后要注意一点 返回的结果集要去除非根节点
// 去除非根节点
resultList = resultList.stream().filter(result -> "0".equals(result.getLastSortId()))
.collect(Collectors.toList());