java – 如何递归flatMap流?
参见英文答案 >
In Java,how do I efficiently and elegantly stream a tree node’s descendants?????????????????????????????????????4个
我被要求检索作为树节点的descandant的每个叶节点.我很快意识到我可以在一条线上完成这项工作! public Set<TreeNode<E>> getLeaves() { return getChildrenStream().flatMap(n -> n.getChildrenStream()).collect(toSet()); } 第一眼看上去很擅长,但很快就遇到StackOverflowExcepetion,树深达到10,这是我无法接受的.后来我开发了一个没有递归和流的实现(但是用我的大脑烤了),但我仍然想知道是否有办法用流做递归flatMaps,因为我发现如果不触及流内部结构就不可能这样做.它需要一个新的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; 看起来并不好.流是一个管道.在添加终端操作之前,不会计算其结果和中间结果.上述方法显然违反了这一原则.它也不像溪流那样容易混淆.我可以递归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; } 开箱即用,我发现这种方法有些不便之处.它确实为最后一次迭代返回一个空Set,并且它正在创建与flatMap一样的流.但是我相信这就是你要找的东西,因为你正在考虑使用flatMap从你想要的地方获得一个递归创建的连接集,其中首先没有创建流.顺便说一句,我已经尝试了-1000级别,它仍然可以很快地运行,没有问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |