我有以下递归调用自己的方法:
public ArrayList<SpecTreeNode> getLeavesBelow()
{
ArrayList<SpecTreeNode> result = new ArrayList<>();
if (isLeaf())
{
result.add(this);
}
for (SpecTreeNode stn : chList)
{
result.addAll(stn.getLeavesBelow());
}
return result;
}
我想将 for 循环转换为使用并行流。我想我部分在那里,但不确定如何将 .collect(( 实现为"addAll"以结果:
chList.parallelStream()
.map(SpecTreeNode::getLeavesBelow)
.collect();
如能提供一些援助,将不胜感激。
就像这样,对吧?我错过了什么吗?
result.addAll(
chList.parallelStream()
.map(SpecTreeNode::getLeavesBelow)
.flatMap(Collection::stream)
.collect(Collectors.toList())
);
与您的问题无关,但因为您正在寻求性能改进:通过为 ArrayList 指定初始大小以避免多次重新分配,您可能会看到一些收益。
如果您无法预测大小,则LinkedList
可能是更可取的数据结构,因为您在此处所做的只是不断追加到列表的末尾。但是,如果您稍后需要随机访问此列表的元素,则可能不需要。
我会通过让递归方法返回节点Stream
而不是List
来做到这一点,然后过滤以仅保留叶子并最终收集到列表中:
public List<SpecTreeNode> getLeavesBelow() {
return nodesBelow(this)
.parallel()
.filter(Node::isLeaf)
.collect(Collectors.toList());
}
private Stream<SpecTreeNode> nodesBelow(SpecTreeNode node) {
return Stream.concat(
Stream.of(node),
node.chList.stream()
.flatMap(this::leavesBelow));
}