递去是什么意思?递去其实就是发现了问题规模还可以再缩小,以相同的解决思路去求出最小的解。递去就是调用递归方法,程序没有直接往下执行,而是先走递归方法。但是没有走的剩下程序它还是会走的,一般除非程序走到了尽头结束了或者抛异常了才不会再执行。
归来是什么意思?归来就是调用递归方法求到解了,递归无法再进行下去了,程序就会回到调用递归方法处,继续走下面的语句,直到走完整个程序。
Controller
@GetMapping
public TagTree list() {
TagTree root = new TagTree();
root.setTagId(0L);
root.setTagName("ceam");
List<SystemTagDef> list = this.tagDefJpa.findAll();
this.child(root, list);
return root;
}
child(TagTree root, List<SystemTagDef> allTags)
private void child(TagTree root, List<SystemTagDef> allTags) {
// 从allTags中取出对应子标签
List<SystemTagDef> childs = allTags.stream().filter(item ->
root.getTagId().equals(item.getParentId())).collect(Collectors.toList());
allTags.removeAll(childs);
// 注意forEach本身就是有终止条件的,即遍历到最后一个元素
childs.forEach(item -> {
TagTree tag = new TagTree();
tag.setTagId(item.getTagId());
tag.setTagName(item.getTagName());
tag.setParentId(item.getParentId());
// 递归调用
this.child(tag , allTags);
root.appendChildren(tag);
});
}
表数据(共7条)
我们重点看看child方法数据变化
1、
root | allTags | remove后的allTags | childs | 第二个item | tag |
ceam | 7条数据 | 5条数据(可可、丫丫、柚柚、微微、贝贝) | 2条数据(一级标签、CeaM) | 一级标签 | 一级标签 |
2、调用this.child(tag , allTags);传入参数值为"一级标签对象",(可可、丫丫、柚柚、微微、贝贝)
root | allTags | remove后的allTags | childs | 第二个item | tag |
一级标签 | 5条数据(可可、丫丫、柚柚、微微、贝贝) | 柚柚、微微、贝贝 | 可可、丫丫 | 可可 | 可可 |
3、调用this.child(tag , allTags);传入参数值为"可可对象",(柚柚、微微、贝贝)
root | allTags | remove后的allTags | childs | 第二个item | tag |
可可 | 柚柚、微微、贝贝 | 柚柚、微微、贝贝 | 1 | 贝贝 | 贝贝 |
4、调用this.child(tag , allTags);传入参数值为"贝贝对象",(柚柚、微微)
root | allTags | remove后的allTags | childs | 第二个item | tag |
贝贝 | 2条数据(柚柚、微微) | 柚柚、微微 | 0 | 0 | 0 |
由于childs为0,即无子项item再不会递归调用,于是回到执行this.child(tag , allTags);下面语句
root.appendChildren(tag);
再执行步骤4前数据场景是3,即root为"可可对象",tag为贝贝。于是将贝贝添加到一级标签
5、 添加贝贝后回到3继续走foreach发现没有item,于是回到2处走下面语句,将可可添加到一级
root.appendChildren(tag);
root | allTags | remove后的allTags | childs | 第二个item | tag |
一级标签 | 2条(柚柚、微微) | 可可 | 可可 |
6、添加可可后继续走foreach,item为丫丫
root | allTags | remove后的allTags | childs | 第二个item | tag |
一级标签 | (柚柚、微微) | 丫丫 | 丫丫 |
7、调用this.child(tag , allTags);传入参数值为"丫丫对象",(柚柚、微微)
root | allTags | remove后的allTags | childs | 第二个item | tag |
丫丫 | (柚柚、微微) | (柚柚、微微) | 0 | 0 | 0 |
由于childs为0,即无子项item再不会递归调用,于是回到执行this.child(tag , allTags);下面语句
root.appendChildren(tag);
再执行步骤7前数据场景是6,即root为"一级标签对象",tag为丫丫。于是将丫丫添加到一级标签
8、添加丫丫后发现一级标签没有item于是结束一级标签遍历回到1执行未走的程序
root.appendChildren(tag);
root | allTags | remove后的allTags | childs | 第二个item | tag |
ceam | (柚柚、微微) | 一级标签 | 一级标签 |
9、将一级标签添加到跟ceam继续forEach遍历item为CeaM
root | allTags | remove后的allTags | childs | 第二个item | tag |
ceam | (柚柚、微微) | CeaM | CeaM |
10、调用this.child(tag , allTags);传入参数值为"CeaM对象",(柚柚、微微)
root | allTags | remove后的allTags | childs | 第二个item | tag |
CeaM | (柚柚、微微) | 0 | (柚柚、微微) | 柚柚 | 柚柚 |
11、走forEach,调用this.child(tag , allTags);传入参数值为"柚柚对象"
root | allTags | remove后的allTags | childs | 第二个item | tag |
柚柚 | 0 | 0 | 0 |
12、发现"柚柚对象"无法走forEach,于是回到10走未走完的程序
root | allTags | remove后的allTags | childs | 第二个item | tag |
CeaM | 0 | 柚柚 | 柚柚 |
root.appendChildren(tag);
13、将柚柚添加到CeaM,继续走forEach
root | allTags | remove后的allTags | childs | 第二个item | tag |
CeaM | 0 | 微微 | 微微 |
14、调用this.child(tag , allTags);传入参数值为"微微对象"
root | allTags | remove后的allTags | childs | 第二个item | tag |
微微 | 0 | 0 | 0 | 0 | 0 |
15、发现"柚柚对象"无法走forEach,于是回到14走未走完的程序
root | allTags | remove后的allTags | childs | 第二个item | tag |
CeaM | 0 | 微微 | 微微 |
root.appendChildren(tag);
16、将微微添加到CeaM后,发现CeaM没有item于是结束CeaM遍历回到9执行未走的程序
root | allTags | remove后的allTags | childs | 第二个item | tag |
ceam | 0 | CeaM | CeaM |
root.appendChildren(tag);
将CeaM添加到ceam后forEach遍历结束,整个程序走完。