我想知道,是否有一个首选的方式来从列表流到包含流中所有列表的元素的集合.
我可以想到两种途径到达那里:
我可以想到两种途径到达那里:
final Stream<List<Integer>> stream = Stream.empty(); final List<Integer> one = stream.collect(ArrayList::new,ArrayList::addAll,ArrayList::addAll); final List<Integer> two = stream.flatMap(List::stream).collect(Collectors.toList());
第二个选项对我来说看起来更好,但我猜第一个在并行流中效率更高.
这两种方法之一是否有进一步的论据?
解决方法
主要的区别是flatMap是
intermediate operation.,而收集是
terminal operation.
因此,如果要执行其他操作而不是立即收集,flatMap是处理展平流项目的唯一方法.
另外收集(ArrayList :: new,ArrayList :: addAll,ArrayList :: addAll)非常难以阅读,因为您有两个相同的方法引用ArrayList :: addAll与完全不同的语义.
关于并行处理,你的猜测是错误的.第一个具有较小的并行处理能力,因为它依赖于ArrayList.add应用于不能被分解成并行子步骤的流项目(子列表).相反,如果流中遇到的特定列表支持它,则应用于flatMap的Collectors.toList()可以执行子列表项的并行处理.但是,只有当你有一个相当大的子列表的时候,这将是相关的.
flatMap的唯一缺点是中间流创建,在您有很多非常小的子列表的情况下会增加开销.
但在你的例子中,流是空的,所以没关系(scnr).