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?
IntStream is a stream of primitive int values. Stream<Integer> is a stream of Integer objects.
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.
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.
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.
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.
Note : IntStream range (int startInclusive, int endExclusive) basically works like a for loop. An equivalent sequence of increasing values can be produced sequentially as :
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 ).
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.
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.
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) { }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With