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级别,它仍然可以很快地运行,没有问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |








