java - 如何递归地 flatMap 一个流?

标签 java recursion java-8 java-stream flatmap

<分区>

我被要求检索作为树节点后裔的每个叶节点。我很快想到我可以在一行中完成这项工作!

public Set<TreeNode<E>> getLeaves() {
    return getChildrenStream().flatMap(n -> n.getChildrenStream()).collect(toSet());
}

乍一看还不错,但很快就遇到了 StackOverflowExcepetion 如果树深度达到 ~10,这是我无法接受的。后来我开发了一个没有递归和流的实现(但是我的大脑),但我仍然想知道是否有办法用流做递归flatMap,因为我发现如果不触及流内部就不可能这样做。它需要一个新的 Op,比如 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;

没有想象中的那么好。流意味着成为管道。在添加终端操作之前,不会计算其结果和中间结果。上述方法显然违反了该原则。 parellelize 也不像流那样容易。我可以在不手动计算所有中间结果的情况下递归 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

最佳答案

不完全确定这是否是您感兴趣的内容:

public static Set<TreeNode<String>> getAllLeaves(TreeNode<String> treeNode) {
    final Stream<TreeNode<String>> childrenStream = treeNode.getChildrenStream();
    if (childrenStream == null) {
        return new HashSet<>();
    }

    Set<TreeNode<String>> ownLeaves = treeNode.getLeaves();
    ownLeaves.addAll(childrenStream.flatMap(stringTreeNode -> getAllLeaves(stringTreeNode).parallelStream())
            .collect(Collectors.toSet()));

    return ownLeaves;
}

开箱即用,我发现这种方法有一些不便之处。它确实为最后一次迭代返回了一个空集,并且它正在像创建 flatMap 一样创建流。但是我相信这就是您正在寻找的,因为您正在考虑使用 flatMap 从您想要递归创建的连接 Set 开始,而首先没有创建流。顺便说一句,我已经用 -1000 级别试过了,它仍然运行得非常快,没有问题。

关于java - 如何递归地 flatMap 一个流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37499628/

相关文章:

java - 使用流和 java8 创建对象列表的字段值的连接字符串

java - Scala Seq.grouped 吃掉我的迭代器

java - OAuth2 spring 示例闪光和色调

recursion - 如何在Haxe中编写相互递归函数

python - 从自身内部调用一个函数

java - lambda 实际上是一个匿名类吗?

java - 为什么/何时应该使用泛型方法?

java - 对 Java 中的不同类型应用通用逻辑

java - java中如何实现递归除法

java - 排序和过滤对象列表