Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between Stream.of and IntStream.range?

Please, consider this code:

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

The output will be:

#1
0
1
2
3

#2
0

Could anyone explain, why output of two streams are different?

like image 491
Pavel_K Avatar asked May 24 '21 09:05

Pavel_K


People also ask

What is the difference between Stream and IntStream?

IntStream is a stream of primitive int values. Stream<Integer> is a stream of Integer objects.

What does IntStream range do?

IntStream range() method in Java The range() method in the IntStream class in Java is used to return a sequential ordered IntStream from startInclusive to endExclusive by an incremental step of 1. This includes the startInclusive as well.

What is an IntStream?

An IntStream interface extends the BaseStream interface in Java 8. It is a sequence of primitive int-value elements and a specialized stream for manipulating int values. We can also use the IntStream interface to iterate the elements of a collection in lambda expressions and method references.

What difference between arrays Stream and Stream of?

Different return types: of() have different return types. Example: Passing an integer array, the Stream. of() method returns Stream whereas Arrays. stream() returns an IntStream.

What is the difference between stream () and stream (of) methods?

Below are some of the differences between the above two stated methods: Different return types: For primitives arrays (like int[], long[] etc), Arrays.stream() and Stream.of() have different return types. Example: Passing an integer array, the Stream.of() method returns Stream whereas Arrays.stream() returns an IntStream.

What is IntStream range in Java?

Note : IntStream range (int startInclusive, int endExclusive) basically works like a for loop. An equivalent sequence of increasing values can be produced sequentially as :

What is the difference between stream of and stream of arrays?

Arrays.stream () method only works for primitive arrays of int [], long [], and double [] type, and returns IntStream, LongStream and DoubleStream respectively. For other primitive types, Arrays.stream () won’t work. On the other hand, Stream.of () returns a generic Stream of type T (Stream ).

How to convert IntStream to stream in Java?

mapToObject will simply return a Stream of the type that the mapping returns. Now, if you just want to convert an IntStream to a Stream<Integer>, there's a dedicated function for this job called boxed. You'll also find map functions that returns DoubleStream and LongStream.


2 Answers

Well, IntStream.range() returns a sequential ordered IntStream from startInclusive(inclusive) to endExclusive (exclusive) by an incremental step of 1, which means it's already sorted. Since it's already sorted, it makes sense that the following .sorted() intermediate operation does nothing. As a result, peek() is executed on just the first element (since the terminal operation only requires the first element).

On the other hand, the elements passed to Stream.of() are not necessarily sorted (and the of() method doesn't check if they are sorted). Therefore, .sorted() must traverse all the elements in order to produce a sorted stream, which allows the findFirst() terminal operation to return the first element of the sorted stream. As a result, peek is executed on all the elements, even though the terminal operation only needs the first element.

like image 79
Eran Avatar answered Oct 14 '22 07:10

Eran


IntStream.range is already sorted:

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

So when sorted() method on the Stream is hit, internally, it will become a NO-OP.

Otherwise, as you already see in your first example, all the elements have to be sorted, only then findFirst can tell who is "really the first one".

Just notice that this optimization only works for naturally sorted streams. For example:

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

where (for brevity):

record User(int age) { }
like image 21
Eugene Avatar answered Oct 14 '22 05:10

Eugene