Bra*_*avo 11 java collections java-8 java-stream
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
List<Integer> twoEvenSquares = numbers.stream().filter(n -> {
System.out.println("filtering " + n);
return n % 2 == 0;
}).map(n -> {
System.out.println("mapping " + n);
return n * n;
}).limit(2).collect(Collectors.toList());
for(Integer i : twoEvenSquares)
{
System.out.println(i);
}
Run Code Online (Sandbox Code Playgroud)
当执行时,输出下面的逻辑来了
filtering 1
filtering 2
mapping 2
filtering 3
filtering 4
mapping 4
4
16
Run Code Online (Sandbox Code Playgroud)
如果流遵循短路概念(我们使用限制流操作),则输出必须如下所示:
filtering 1
filtering 2
filtering 3
filtering 4
mapping 2
mapping 4
4
16
Run Code Online (Sandbox Code Playgroud)
因为在过滤2之后,我们还要找到一个元素来分层限制(2),操作,那么为什么输出不像我解释的那样?
Mar*_*eel 20
流是基于拉的.只有终端操作(如collect
)会导致消耗物品.
从概念上讲,这意味着collect
将要求一个项目从limit
,limit
从map
和map
从filter
,并filter
从流.
示意性地,您的问题中的代码会导致
collect
limit (0)
map
filter
stream (returns 1)
/filter (false)
filter
stream (returns 2)
/filter (true)
/map (returns 4)
/limit (1)
limit (1)
map
filter
stream (returns 3)
/filter (false)
filter
stream (returns 4)
/filter (true)
/map (returns 16)
/limit (2)
limit (2)
/limit (no more items; limit reached)
/collect
Run Code Online (Sandbox Code Playgroud)
这符合您的第一次打印输出.
这是中间流操作的延迟执行/评估的结果.
操作的链以相反的顺序从去被懒惰地评估collect()
到filter()
,值由每个步骤只要它们是由前一步骤中产生的消耗.
更清楚地描述正在发生的事情:
collect()
开始评估链.limit()
开始评估其祖先map()
开始评估其祖先filter()
开始消耗源流中的值1
评估,2
评估并生成第一个值map()
消耗其祖先返回的第一个值并产生一个值limit()
消耗这个价值 collect()
收集第一个值limit()
需要来自map()
源的另一个值map()
需要来自它祖先的另一个价值filter()
恢复评估以产生另一个结果并在评估3
并4
产生新值之后4
map()
消耗它并产生新的价值limit()
使用新值并返回它collect()
收集最后一个值.流操作分为中间操作和终端操作,并组合成流管道.流管道由源(例如集合,数组,生成器函数或I/O通道)组成; 然后是零个或多个中间操作,例如Stream.filter或Stream.map; 和一个终端操作,如Stream.forEach或Stream.reduce.
中间操作返回一个新流.他们总是懒惰 ; 执行诸如filter()之类的中间操作实际上并不执行任何过滤,而是创建一个新流,当遍历时,该流包含与给定谓词匹配的初始流的元素.在执行管道的终端操作之前,不会开始遍历管道源.
您注意到的行为是正确的。为了查明某个数字是否通过了整个 Stream 管道,您必须在所有管道步骤中运行该数字。
filtering 1 // 1 doesn't pass the filter
filtering 2 // 2 passes the filter, moves on to map
mapping 2 // 2 passes the map and limit steps and is added to output list
filtering 3 // 3 doesn't pass the filter
filtering 4 // 4 passes the filter, moves on to map
mapping 4 // 4 passes the map and limit steps and is added to output list
Run Code Online (Sandbox Code Playgroud)
现在管道可以结束了,因为我们有两个数字通过了管道。
归档时间: |
|
查看次数: |
5356 次 |
最近记录: |