文章目录
- 递归实现
- 一、普通递归
- 二、jdk8 stream递归
- 总结
- 补充
- 简单解释下
递归实现
递归,顾名思义,自己调用自己,在java开发中,多用于构造类似菜单等业务数据的树形结构,层层嵌套;
一、普通递归
测试方法
@Test
void treelist() {
List<Tree> trees = initList(); // 模拟获取数据
List<Tree> list = getTrees("0", trees);
root.setList(list);
System.out.println(JSONUtil.toJsonPrettyStr(root));
}
initList
private List<Tree> initList() {
List<Tree> trees = new ArrayList<>();
trees.add(new Tree("0", "root"));
trees.add(new Tree("2", "0"));
trees.add(new Tree("6", "2"));
trees.add(new Tree("7", "6"));
trees.add(new Tree("3", "1"));
trees.add(new Tree("4", "1"));
trees.add(new Tree("5", "4"));
trees.add(new Tree("7", "6"));
trees.add(new Tree("5", "4"));
trees.add(new Tree("1", "0"));
return trees;
}
Tree
@Data
public class Tree {
String id;
String pid;
List<Tree> list;
public Tree(String id, String pid) {
this.id = id;
this.pid = pid;
}
public Tree() {
}
}
getTrees 方法
// 递归为树
private List<Tree> getTrees(String id, List<Tree> trees) {
List<Tree> list = new ArrayList<>();
for (Tree tree : trees) {
if (tree.getPid().equals(id)) {
tree.setList(getTrees(tree.getId(), trees));
list.add(tree);
}
}
return list;
}
二、jdk8 stream递归
@Test
void treelist() {
List<Tree> trees = initList();
Tree root = trees.stream().filter(tree -> tree.getId().equalsIgnoreCase("0")).collect(toList()).get(0);
List<Tree> childrenStream = getChildrenStream(root,trees);
root.setList(childrenStream);
System.out.println(JSONUtil.toJsonPrettyStr(root));
}
实体类和上述一样
getChildrenStream 方法
private List<Tree> getChildrenStream(Tree root, List<Tree> trees) {
return trees.stream().filter(tree -> tree.getPid().equalsIgnoreCase(root.getId())) // 返回root 的子节点
.peek(tree -> tree.setList(getChildrenStream(tree,trees))).collect(Collectors.toList()); // peek 设置当前节点的子节点
}
总结
两种方法对比,当然java8 效率更高,代码更简洁
补充
今天用到了删除功能,也就是递归删除,那么就需要递归找到所有集合,也就是递归寻找数据,返回集合,直接开干
@Test
void treeListStream() {
List<Tree> trees = initList();
Tree root = trees.stream().filter(tree -> tree.getId().equalsIgnoreCase("0")).collect(toList()).get(0);
List<Tree> childrenStream = CollectionUtil.newArrayList();
getChildrenList(root, trees, childrenStream);
System.out.println(JSONUtil.toJsonPrettyStr(childrenStream));
}
private List<Tree> getChildrenList(Tree root, List<Tree> trees, List<Tree> childrenStream) {
List<Tree> collect = trees.stream().filter(tree -> tree.getPid().equals(root.getId()))
.peek(tree -> getChildrenList(tree, trees, childrenStream))
.collect(toList());
childrenStream.addAll(collect);
return collect;
}
简单解释下
1 childrenStream 用来装每次递归找到的子集
2 .peek 以当前找到的子节点为父节点 再次递归调用方法,寻找子集,然后也被放入了childrenStream 集合中;