Java8流执行
你能解释一下下面代码的执行过程吗?主要是Java8流执行,java,java-8,java-stream,Java,Java 8,Java Stream,你能解释一下下面代码的执行过程吗?主要是排序方法 Stream.of("d2", "a2", "b1", "b3", "c") .sorted((s1, s2) -> { System.out.printf("sort: %s; %s\n", s1, s2); return s1.compareTo(s2); }) .filter(s -> { System.out.println("filter: " + s)
排序
方法
Stream.of("d2", "a2", "b1", "b3", "c")
.sorted((s1, s2) -> {
System.out.printf("sort: %s; %s\n", s1, s2);
return s1.compareTo(s2);
})
.filter(s -> {
System.out.println("filter: " + s);
return s.startsWith("a");
})
.map(s -> {
System.out.println("map: " + s);
return s.toUpperCase();
})
.forEach(s -> System.out.println("forEach: " + s));
输出:
sort: a2; d2
sort: b1; a2
sort: b1; d2
sort: b1; a2
sort: b3; b1
sort: b3; d2
sort: c; b3
sort: c; d2
filter: a2
map: a2
forEach: A2
filter: b1
filter: b3
filter: c
filter: d2
谢谢,Ref:因此
Java8
尝试通过对任何给定输入尽快执行所有高阶函数来加速执行。也就是说,例如,如果在列表中的一行中调用两次map
,那么它将只访问列表中的每个元素一次。这会加快它的速度,因为它会从列表中的2次传递变为1次。为了说明这一点,我们举一个简单的例子:
Stream.of(1, 2, 3)
.map(s -> {
System.out.println("map: " + s.toString());
return s;
})
.map(s -> {
System.out.println("map: " + s.toString());
return s;
})
这将打印:
1
1
2
2
3
3
因为对于map
s,一次“触摸”列表中的每个元素比完全遍历列表要快
就你的例子而言,让我们一件一件地看:
sort: a2; d2
sort: b1; a2
sort: b1; d2
sort: b1; a2
sort: b3; b1
sort: b3; d2
sort: c; b3
sort: c; d2
所有排序都需要同时进行,而且都需要首先进行。这是因为在排序完成之前,计算机无法知道哪个元素将位于哪个位置(即,它不能在同一列表位置上映射两次,因为排序可能会改变这一点)
接下来,您基本上有以下内容:
Stream.of("a2", "b1", "b3", "c", "d2")
.filter(s -> {
System.out.println("filter: " + s);
return s.startsWith("a");
})
.map(s -> {
System.out.println("map: " + s);
return s.toUpperCase();
})
.forEach(s -> System.out.println("forEach: " + s));
现在,为了尽量减少通过列表的次数,Java将遍历列表中的每个元素并执行过滤器
,然后执行映射
,然后执行forEach
。这是因为这些都不取决于元素的位置。换句话说,Java认为它可以对每个元素执行所有这些操作,而不是对每个函数对整个列表进行三次迭代
现在:
我们过滤第一个元素,然后在它上面映射,然后对每个元素进行最后的打印
filter: b1
filter: b3
filter: c
filter: d2
这些都被过滤掉了,所以剩下的函数不会被调用 您似乎对输出中连续出现多个排序调用感到困惑 让我们来解释一下;首先,中间操作分为无状态(如
过滤器
,映射
等)和有状态(如排序
,不同
等)
正如Brian Goetz所提到的:
无状态操作是可以对元素执行的操作
不知道任何其他元素。例如,一个
筛选操作只需检查当前元素即可
确定是包含还是删除它,而是一个排序操作
必须先查看所有元素,然后才能知道首先发射哪个元素
我的
排序操作在将给定元素发送给下一个操作之前必须看到所有元素,这就是为什么在输出中连续看到几个排序调用的原因
此外,您可能还想阅读
它在某种程度上派生了
排序的操作 你有具体的问题吗?
filter: b1
filter: b3
filter: c
filter: d2