我试图了解如何调用非终端流操作。
Stream.of("aaa", "bbb", "ccc")
.map(s -> {
System.out.println(s);
return s.toUpperCase();
});
//prints nothing
Stream.of("aaa", "bbb", "ccc")
.map(s -> {
System.out.println(s);
return s.toUpperCase();
})
.forEach(s -> {});
//prints "aaa" "bbb" "ccc"
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎很清楚。
第一个流未以终端操作结束,因此它不会调用非终端操作,并且不会打印任何内容。第二个有终端操作,因此所有元素都会被打印。
Stream.of("aaa", "bbb", "ccc")
.map(s -> {
System.out.println(s);
return s.toUpperCase();
})
.findFirst();
//prints "aaa"
Stream.of("aaa", "bbb", "ccc")
.map(s -> {
System.out.println(s);
return s.toUpperCase();
})
.filter(s -> s.startsWith("B"))
.findFirst();
//prints "aaa" "bbb"
Run Code Online (Sandbox Code Playgroud)
这是我感到困惑的地方,尤其是最后一个。看起来该流在某种意义上是“向后”工作的。首先,它检查终端操作返回哪些元素,然后仅对这些元素执行中间操作。但最后一个怎么解释呢?看起来它对所有元素进行了映射,直到第一个与过滤器匹配的元素为止。在最后一个示例中,如果我替换findFirst()为forEach(),它会打印所有元素,即使它最后只有一个元素。
对我来说似乎有点违反直觉。谁能给我正确的解释流如何识别它应该执行中间操作的元素?