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();

输出将是:

#1
0
1
2
3

#2
0

谁能解释一下,为什么两个流的输出不同?

回答

嗯,IntStream.range()返回a sequential ordered IntStream from startInclusive(inclusive) to endExclusive (exclusive) by an incremental step of 1,这意味着它已经排序。既然已经排序了,那么下面的.sorted()中间操作什么都不做是有道理的。结果,peek()只在第一个元素上执行(因为终端操作只需要第一个元素)。

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

  • @ernest_k 1. After thinking about it more, compiler optimization seems less likely. I think the `or at least does nothing` part is more likely to be the case. 2. what kind of elaboration do you think is missing? I wrote in the second paragraph why `sorted` usually needs to traverse all the elements.
  • @ernest_k it is a runtime optimization only, and a bit fragile too
  • 2 things: 1. is this a compiler optimization? seems like you imply that. 2. Would be helpful if you elaborate on `sorted()` making a difference (for peek) by needing all elements... Good answer, btw.

回答

IntStream.range已经进行排序:

// reports true
System.out.println(
       IntStream.range(0, 4)
                .spliterator()
                .hasCharacteristics(Spliterator.SORTED)
);

所以当sorted()Stream 上的方法被命中时,在内部,它会变成一个 NO-OP。

否则,正如您在第一个示例中已经看到的那样,所有元素都必须排序,只有这样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();

其中(为简洁起见):

record User(int age) { }


以上是Stream.of和IntStream.range有什么区别?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>