Using Generator Functions to Build Infinite Streams – Streams
Using Generator Functions to Build Infinite Streams
The generate() and iterate() methods of the core stream interfaces can be used to create infinite sequential streams that are unordered or ordered, respectively.
Infinite streams need to be truncated explicitly in order for the terminal operation to complete execution, or the operation will not terminate. Some stateful intermediate operations must process all elements of the streams in order to produce their results—for example, the sort() intermediate operation (p. 929) and the reduce() terminal operation (p. 955). The limit(maxSize) intermediate operation can be used to limit the number of elements that are available for processing from a stream (p. 917).
Generate
The generate() method accepts a supplier that generates the elements of the infinite stream.
IntSupplier supplier = () -> (int) (6.0 * Math.random()) + 1; // (1)
IntStream diceStream = IntStream.generate(supplier); // (2)
diceStream.limit(5) // (3)
.forEach(i -> System.out.print(i + ” “)); // (4) 2 4 5 2 6
The IntSupplier at (1) generates a number between 1 and 6 to simulate a dice throw every time it is executed. The supplier is passed to the generate() method at (2) to create an infinite unordered IntStream whose values simulate throwing a dice. In the pipeline comprising (3) and (4), the number of values in the IntStream is limited to 5 at (3) by the limit() intermediate operation, and the value of each dice throw is printed by the forEach() terminal operation at (4). We can expect five values between 1 and 6 to be printed when the pipeline is executed.
Iterate
The iterate() method accepts a seed value and a unary operator. The method generates the elements of the infinite ordered stream iteratively: It applies the operator to the previous element to generate the next element, where the first element is the seed value.
In the code below, the seed value of 1 is passed to the iterate() method at (2), together with the unary operator uop defined at (1) that increments its argument by 2. The first element is 1 and the second element is the result of the unary operator applied to 1, and so on. The limit() operation limits the stream to five values. We can expect the forEach() operation to print the first five odd numbers.
IntUnaryOperator uop = n -> n + 2; // (1)
IntStream oddNums = IntStream.iterate(1, uop); // (2)
oddNums.limit(5)
.forEach(i -> System.out.print(i + ” “)); // 1 3 5 7 9
The following stream pipeline will really go bananas if the stream is not truncated by the limit() operation:
Stream.iterate(“ba”, b -> b + “na”)
.limit(5)
.forEach(System.out::println);
Leave a Reply