'Why can do distinct() method at infinite stream in java

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        new Random().ints(1, 45 + 1) // (1)
                .distinct()  // (2)
                .limit(6)
                .sorted()
                .forEach(System.out::println);
    }
}

new Random().ints is infinite stream.

I guess, infinite stream can't distinct because infinite stream continues to grow.

but this code is possible.

how it works?



Solution 1:[1]

Because of .limit(6) result isn't infinite. Streams doesn't produce whole result on each operation.

Solution 2:[2]

Streams are built on the concept of lazy evaluation. This means that each operator (distinct in your case) does not consume the complete stream of elements before the next operator is applied.

So each element of the stream is passed through all operators until it reaches a terminal operator. Then the next element of stream is passed through all operators again until it reaches a terminal operator. This is the reason your operator distinct is able to work on a provided as you say infinite stream.

limit is the terminal operator which is used in your case. You can observe how this works by intercepting the elements with peek. Check the following and you will be able to understand how streams work in a lazy concept as said before until they reach a terminal operator.

new Random().ints(1, 45 + 1) // (1)
                .peek(el -> System.out.println("Before distinct " + el))
                .distinct()  // (2)
                .peek(el -> System.out.println("After distinct " + el))
                .limit(6)
                .peek(el -> System.out.println("After limit " + el))
                .sorted()
                .forEach(System.out::println);

Will print

Before distinct 8
After distinct 8
After limit 8
Before distinct 45
After distinct 45
After limit 45
Before distinct 16
After distinct 16
After limit 16
Before distinct 34
After distinct 34
After limit 34
Before distinct 9
After distinct 9
After limit 9
Before distinct 25
After distinct 25
After limit 25   <---- Here the limit of 6 elements is covered so the first stream is completed.
8
9
16
25
34
45

Also take a look on this SO answer to see a similar investigation of the past.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 talex
Solution 2