【发布时间】:2016-05-28 13:30:26
【问题描述】:
我被要求检索作为树节点的 descandant 的每个叶节点。我很快就想到我可以一口气完成这项工作!
public Set<TreeNode<E>> getLeaves() {
return getChildrenStream().flatMap(n -> n.getChildrenStream()).collect(toSet());
}
乍一看还不错,但如果树的深度达到 ~10,它很快就遇到了StackOverflowExcepetion,这是我无法接受的。后来我开发了一个没有递归和流的实现(但我的大脑烤),但我仍然想知道是否有办法使用流进行递归flatMaps,因为我发现它不可能这样做而不接触流内部。它需要一个新的操作,例如 RecursiveOps 来执行此操作,否则我必须将所有结果收集到每个步骤的 Set 中,然后再对 Set 进行操作:
Set<TreeNode<E>> prev = new HashSet<>();
prev.add(this);
while (!prev.isEmpty()) {
prev = prev.stream().flatMap(n -> n.getChildrenStream()).collect(toSet());
}
return prev;
看起来并不好。流意味着是一个管道。在添加终端操作之前,不会计算其结果和中间结果。上述做法显然违反了这一原则。并行化也不像流那么容易。我可以在不手动计算所有中间结果的情况下递归 flatMap 吗?
PS1:TreeNode 声明:
public class TreeNode<E> {
// ...
/**
* Get a stream of children of the current node.
*
*/
public Stream<TreeNode<E>> getChildrenStream(){
// ...
}
public Set<TreeNode<E>> getLeaves() {
// main concern
}
}f
【问题讨论】:
-
这看起来与另一个问题stackoverflow.com/questions/32749148/… 非常相关。它回答了你的问题吗? (这不是一个简单的问题)
-
@Tunaki 谢谢,这就是我要找的。不过没有用那个关键字搜索。
标签: java recursion java-8 java-stream flatmap