这是一个例子: 代码A:
files.forEach(f -> {
//TODO
});
和另一个代码B可以这样使用:
files.stream().forEach(f -> { });
两者之间有什么区别,stream()
和没有stream()
?
答案 0 :(得分:17)
实际上,它们大致相同,但语义上有一点小差异。
代码A由Iterable.forEach
定义,而代码B由Stream.forEach
定义。 Stream.forEach
的定义允许以任何顺序处理元素 - 即使对于顺序流也是如此。 (对于并行流,Stream.forEach
很可能会无序处理元素。)
Iterable.forEach
从源代码获取Iterator并在其上调用forEachRemaining()
。据我所知,集合类上的所有当前(JDK 8)Stream.forEach
实现将创建一个源自其中一个迭代器的Spliterator,然后在该迭代器上调用forEachRemaining
- 就像Iterable.forEach
一样。所以他们做同样的事情,虽然流版本有一些额外的设置开销。
但是,将来,流实现可能会发生变化,因此不再是这种情况。
(如果您想保证处理流元素的排序,请改用forEachOrdered()
。)
答案 1 :(得分:2)
语义方面没有区别,但没有stream
的直接实现可能稍微有效。
答案 2 :(得分:0)
流是用于耗尽操作或迭代的元素序列(即数据结构)。任何集合都可以作为流公开。您在流上执行的操作可以是
中间操作(map,skip,concat,substream,distinct,filter,sorted,limit,peek ..)生成另一个java.util.stream.Stream,但中间操作是延迟操作,只有在执行终端操作后才会执行。
终端操作(forEach,max,count,matchAny,findFirst,reduce,collect,sum,findAny)生成一个非流的对象。
基本上它与Unix中的管道类似。
答案 3 :(得分:-2)
两种方法都使用终端操作Iterable.forEach
,但带有.stream()
的版本也不必要地创建表示List的Stream
对象。虽然没有区别,但它并不是最理想的。