Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Stream.of和IntStream.range之间有什么区别? 请考虑这个代码: System.out.println("#1"); Stream.of(0, 1, 2, 3) .peek(e -> System.out.println(e)) .sorted() .findFirst(); System.out.println("\n#2"); IntStream.range(0, 4) .peek(e -> System.out.println(e)) .sorted() .findFirst();_Java_Java Stream - Fatal编程技术网

Java Stream.of和IntStream.range之间有什么区别? 请考虑这个代码: System.out.println("#1"); Stream.of(0, 1, 2, 3) .peek(e -> System.out.println(e)) .sorted() .findFirst(); System.out.println("\n#2"); IntStream.range(0, 4) .peek(e -> System.out.println(e)) .sorted() .findFirst();

Java Stream.of和IntStream.range之间有什么区别? 请考虑这个代码: System.out.println("#1"); Stream.of(0, 1, 2, 3) .peek(e -> System.out.println(e)) .sorted() .findFirst(); System.out.println("\n#2"); IntStream.range(0, 4) .peek(e -> System.out.println(e)) .sorted() .findFirst();,java,java-stream,Java,Java Stream,输出将是: #1 0 1 2 3 #2 0 有人能解释一下,为什么两个流的输出是不同的吗?嗯,IntStream.range()以1的增量步骤返回从startInclusive(包含)到endExclusive(排除)的顺序IntStream,这意味着它已经排序了。因为它已经被排序,所以下面的.sorted()中间操作什么都不做是有意义的。因此,peek()只在第一个元素上执行(因为终端操作只需要第一个元素) 另一方面,传递给Stream.of()的元素不一定要排序(并且of()方法不检查它

输出将是:

#1
0
1
2
3

#2
0

有人能解释一下,为什么两个流的输出是不同的吗?

嗯,
IntStream.range()
以1的增量步骤返回
从startInclusive(包含)到endExclusive(排除)的顺序IntStream,这意味着它已经排序了。因为它已经被排序,所以下面的
.sorted()
中间操作什么都不做是有意义的。因此,
peek()
只在第一个元素上执行(因为终端操作只需要第一个元素)


另一方面,传递给
Stream.of()
的元素不一定要排序(并且
of()
方法不检查它们是否已排序)。因此,
.sorted()
必须遍历所有元素以生成排序流,这允许
findFirst()
终端操作返回排序流的第一个元素。因此,对所有元素执行
peek
,即使终端操作只需要第一个元素。

IntStream.range
已排序:

因此,当流上的
sorted()
方法被命中时,它将在内部被命中

否则,正如您在第一个示例中已经看到的,所有元素都必须进行排序,只有这样
findFirst
才能判断谁是“真正的第一个”


请注意,此优化仅适用于自然排序的流。例如:

// prints too much you say?
Stream.of(new User(30), new User(25), new User(34))
            .peek(x -> System.out.println("1 : before I call first sorted"))
            .sorted(Comparator.comparing(User::age))
            .peek(x -> System.out.println("2 : before I call second sorted"))
            .sorted(Comparator.comparing(User::age))
            .findFirst();
其中(为简洁起见):


有趣的优化!我认为
.sorted()
IntStream
上只是noops,因为它已经知道它已经被排序了。一般来说,
peek
是否会实际观察给定的元素是不可预测的,取决于实现。它仅用于调试目的。除了您所问的和答案中所回答的区别之外,另一个区别是
Stream.of(0,1,2,3)
给您一个
Stream
,而
IntStream.range(0,4)
给您一个
IntStream
,一个
int
原语流。我是这么说的,但我也要说,它是一个实现细节,无论元素是否被使用,除了少数指定这一点的流方法。在许多常见的场景中,
peek
可以做很多不同的事情。@sp00m但是它不能在
O(1)
中执行
max
min
<代码>IntStream.range(0,4).peek(System.out::println).max();//生成0,1,2,3
。为什么不在这里使用相同的优化?2件事:1。这是编译器优化吗?你好像是在暗示。2.如果您详细说明
sorted()。。。回答得好,顺便说一句@ernest_k 1。仔细考虑之后,编译器优化似乎不太可能。我认为
或至少什么也不做的部分更可能是这样。2.你认为缺少什么样的阐述?我在第二段中写到了为什么排序后的
通常需要遍历所有元素。@ernest_k这只是一个运行时优化,也有点脆弱“请注意,此优化只适用于自然排序的流”我想这是有道理的,布尔“排序”标志只跟踪一种类型的“排序”,跟踪其他类型会非常复杂(您需要像
Map
这样的东西来跟踪它们。可能与实现细节有关,但是如果流的特征确定要执行No-Op,那么这样的优化不能在
IntStream.range(0,4).peek(System.out::println.max()中使用吗;//输出0,1,2,3
?在排序列表上,执行最大值和最小值应该是
O(1)
对吗?@Naman yup,我记得有几次讨论过这个问题。只是“还没有”实现。
// prints too much you say?
Stream.of(new User(30), new User(25), new User(34))
            .peek(x -> System.out.println("1 : before I call first sorted"))
            .sorted(Comparator.comparing(User::age))
            .peek(x -> System.out.println("2 : before I call second sorted"))
            .sorted(Comparator.comparing(User::age))
            .findFirst();
record User(int age) { }