先贴出实际应用
0总体思想
实体 A的数据库字段包含 a_uuid(本身uuid),a_parent_uuid(父节点uuid)
业务字段有 children(该节点的子节点),childrenFlag(有无子节点的标志)
根节点没有父节点,可以设置为根节点的parent=0(作为根节点的标志)
1递归list转树
1查询该数据的所有
List<A> all=;
2获取根节点
//将list转换成树结构的A对象 返回前端
A parent = XX.selectOne;
3递归获取 每个节点的子节点(每次都把每个节点当作根节点去递归查询其子节点,直至没有子节点为止)
A trees = recursiveTree(parent, all);
整体代码
/**
* 递归list:list转树结构
*
* @param parentNode 某个父节点
* @param AllList 所有节点信息
* @return 获取某个父节点下的所有子节点
*/
public SimuSubjectTask recursiveTree(A parentNode, List<A> AllList) {
//获取子节点
List<A> childTreeNodes = findChildrenTree(parentNode.getAUuid(), AllList);
//若子节点不为空,则将子节点添加至所属父节点信息中
if (!CollectionUtils.isEmpty(childTreeNodes)) {
List<A> childList = new ArrayList<>();
for (Achild : childTreeNodes) {
//继续向下找子节点
SimuSubjectTask item = recursiveTree(child, AllList);
//存储子节点
childList.add(item);
}
//获取非数据库字段展示(children,childrenFlag,)
parentNode.setChildren(childList);
parentNode.setChildrenFlag("1");
}
return parentNode;
}
//获取子节点list
public List<A> findChildrenTree(String aUuid, List<A> AllList) {
List<A> childNodes = new ArrayList<>();
for (A item : AllList) {
if (Objects.equals(item.getAParentUuid(), aUuid)) {
childNodes.add(item);
}
}
return childNodes;
}
另一个用法使用hutool将list转成tree
官方文档
实际应用
注意一下 树的结构的名称也就相当于map的key,注意树型结构的对应关系即可
2树转list
/**
* tree转换为list
*
* @param tree
* @return
*/
public List<A> treeToList(A tree, String pid) {
List<A> resultList = new ArrayList<>();
tree.setAParentUuid(pid);
if (tree.getChildren() != null && tree.getChildren().size() > 0) {
for (Ait : tree.getChildren()) {
resultList.addAll(treeToList(it, it.getAParentUuid()));
tree.setChildren(null);
resultList.add(tree);
}
} else {
resultList.add(tree);
}
return resultList;
}
list转树:入参是pid(为根节点),和一个空tree
1.递归
涉及到递归的返回值,递归的原理
递归会不断的开辟内存,存入副本,因此耗时间
cuking
其实递归也是如此,从根本上来说,递归调用其实调用的并不是本身,你写在程序里的一个函数,调用它其实并不是真的执行了它,而是开辟了一份空间,把其中的数据(包括参数,和函数里的一些变量等),存在其中,然后根据你写的代码去修改这些数据,每次调用一个函数,就会开辟一份这样的空间,执行完毕之后释放,而递归的时候,每一次递归调用都会开辟一份这样的空间,互相独立,所以才有本段开头的一句话,所以,如果一次递归调用共调用了N次,你就可以理解为你写了N个函数,只不过它们长得一样罢了。
(1)使用循环
海绵般汲取
(2)使用stream,将平铺的数据转换成树形结构
我的实际应用悲凉的秋风
掉发的小王
2.for each循环
首先有个pid即根节点之后,遍历树找到pid是根节节点的节点,放在pid下的根下。
3.mybatis语句(xml)/mybatis plus使用注解
mybatis与mybatis plus的区别也体现在这里。在程序中如果select语句的条件比较复杂,不建议写在注解上面,而是写在xml中,其中mybatis的xml比较死板需要配置参数映射,而mybatis plus的xml会自动映射配置
TheTSing
xml语句中的select="gethoustreechildren"就相当于一个函数,column是入参,返回值是property=“children”