gpt4 book ai didi

java - Java 流阶段是连续的吗?

转载 作者:搜寻专家 更新时间:2023-10-30 21:01:02 24 4
gpt4 key购买 nike

我有一个关于中间阶段顺序状态的问题 - 一个阶段的操作是否应用于所有输入流(项目)是所有阶段/操作应用于每个流项目?

我知道这个问题可能不太容易理解,所以我举个例子。在下面的流处理中:

List<String> strings = Arrays.asList("Are Java streams intermediate stages sequential?".split(" "));
strings.stream()
.filter(word -> word.length() > 4)
.peek(word -> System.out.println("f: " + word))
.map(word -> word.length())
.peek(length -> System.out.println("m: " + length))
.forEach(length -> System.out.println("-> " + length + "\n"));

我对这段代码的期望是它会输出:

f: streams
f: intermediate
f: stages
f: sequential?

m: 7
m: 12
m: 6
m: 11

-> 7
-> 12
-> 6
-> 11

相反,输出是:

f: streams
m: 7
-> 7

f: intermediate
m: 12
-> 12

f: stages
m: 6
-> 6

f: sequential?
m: 11
-> 11

由于控制台输出,所有阶段的项目是否都显示?或者它们是否也在所有阶段处理,一次一个?

如果问题不够清楚,我可以进一步详细说明。

最佳答案

此行为可以优化 代码。如果每个中间操作要在继续下一个中间操作之前处理流的所有元素,那么将没有机会进行优化

因此,为了回答您的问题,每个元素一次一个地沿流管道垂直移动(稍后讨论的一些有状态操作除外),因此尽可能进行优化.

说明

鉴于您提供的示例,每个元素将沿着流管道垂直移动一个接一个,因为不包括有状态操作。

另一个例子,假设你正在寻找长度大于 4 的第一个 String,在提供结果之前处理所有元素是不必要且耗时的.

考虑这个简单的例子:

List<String> stringsList = Arrays.asList("1","12","123","1234","12345","123456","1234567");
int result = stringsList.stream()
.filter(s -> s.length() > 4)
.mapToInt(Integer::valueOf)
.findFirst().orElse(0);

上面的filter 中间操作将不会找到所有长度大于4 的元素并返回它们的新流,而是一旦我们找到第一个长度大于 4 的元素,该元素就会进入 .mapToInt,然后 findFirst说“我找到了第一个元素”并且执行在那里停止。因此结果将为 12345

有状态和无状态中间操作的行为

请注意,当诸如sorted 之类的有状态中间操作包含在流管道中时,特定 操作将遍历整个流 .如果您考虑一下,这是完全有道理的,因为为了对元素进行排序,您需要查看所有元素以确定哪些元素在排序顺序中排在第一位。

distinct 中间操作也是有状态操作,但是,正如@Holger 提到的,与sorted 不同,它不需要遍历整个流,因为每个不同的元素都可以立即通过管道向下传递并可能满足短路条件。

filtermap 等无状态中间操作不必遍历整个流,可以像上面提到的那样在垂直方向上一次自由地处理一个元素。

最后但同样重要的是要注意,当终端操作是短路操作时,终端短路方法可以在遍历底层流的所有元素之前完成。

阅读: Java 8 stream tutorial

关于java - Java 流阶段是连续的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44862517/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com