Java 8 Streams API - creating infinite streams with iterate and generate methods
Introduction
This tutorial explains how to create infinite streams using the Java 8 Stream API's
Since infinite streams need to be limited to a finite number, based on specific requirement, hence it is a common practice to limit the number of elements produced by a stream using the
Let us now take a look at how
Where,
- first input parameter is a seed value or initial value of type T
- second input parameter is a
- output is a
So,
The 1st value in the infinite
The 2nd value will be ƒ(seed-value).
The 3rd value will be ƒ(ƒ(seed-value))
The 4th value will be ƒ(ƒ(ƒ(seed-value))) and so on...
Let us take an example to understand how
Suppose the
So,
The 1st value returned in the infinite stream will be 2
The 2nd value returned in the stream will be fsqr(2) OR 2*2=4.
The 3rd value will be fsqr(fsqr(2)) i.e. fsqr(4) OR 4*4=16
The 4th value will be fsqr(fsqr(fsqr(2))) i.e. fsqr(16) OR 16*16=256 and so on...
The infinite stream will then have values - [2,4,16,256,... and so on...]
The Java code for using
OUTPUT of the above code
Explanation of the code
Creating infinite Streams using the
Where,
- Only input is an instance of a Supplier Functional Interface of Type T
- Output is a
Let us now look at how to write the code to create an infinite stream containing random values using
OUTPUT of the above code
Explanation of the code
iterate()
and generate()
methods with examples to show their usage. This tutorial assumes that you are familiar with basics of Java 8 Streams APIRead Basics of Java 8 Streams API.
Infinite Streams
Streams are different from collections although they can be created from collections. Unlike collections, a stream can go on generating/producing values forever. Java 8 Streams API provides two static methods in the Stream interface for creating infinite streams. These are Stream.iterate()
and Stream.generate()
.Since infinite streams need to be limited to a finite number, based on specific requirement, hence it is a common practice to limit the number of elements produced by a stream using the
Stream.limit()
method.Let us now take a look at how
Stream.iterate()
and Stream.generate()
methods can be used to produce infinite streams.
Creating infinite Streams using the Stream.iterate()
method
Let us start by looking at the signature of Stream.iterate()
method - static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
- first input parameter is a seed value or initial value of type T
- second input parameter is a
UnaryOperator
function of type T- output is a
Stream
of type TStream.iterate()
method works just like a function-of algebraic operation which is commonly written as ƒ(x). The method first returns the seed-value itself. For the 2nd element in the Stream it finds ƒ(seed-value) and from then on iteratively keeps applying function-of to the returned values.So,
The 1st value in the infinite
Stream<T>
will be the seed-value The 2nd value will be ƒ(seed-value).
The 3rd value will be ƒ(ƒ(seed-value))
The 4th value will be ƒ(ƒ(ƒ(seed-value))) and so on...
Let us take an example to understand how
Stream.iterate()
method works - Suppose the
UnaryOperator<T>
function fsqr() is a square function defined using the lambda expression - (Integer n) -> n*n
and the seed
is 2.So,
The 1st value returned in the infinite stream will be 2
The 2nd value returned in the stream will be fsqr(2) OR 2*2=4.
The 3rd value will be fsqr(fsqr(2)) i.e. fsqr(4) OR 4*4=16
The 4th value will be fsqr(fsqr(fsqr(2))) i.e. fsqr(16) OR 16*16=256 and so on...
The infinite stream will then have values - [2,4,16,256,... and so on...]
The Java code for using
Stream.iterate()
method to produce a Stream of iteratively squared values will be as below - Java 8 code to produce an infinite Stream using Stream.iterate()
package com.javabrahman.java8.streams;
import java.util.stream.Stream;
public class InfiniteStreams {
public static void main(String args[]){
Stream.iterate(2, (Integer n) -> n*n)
.limit(5)
.forEach(System.out::println);
}
}
2 4 16 256 65536
Seed
passed as input to theStream.iterate()
method is2
.UnaryOperator
function instance is passed using the lambda expression-(Integer n) -> n*n
.- The output stream is limited to
5
elements usingStream.limit()
method. - Output
Stream
is as expected with values -2,4,16,256,65536
.
Stream.generate()
method
Stream.generate()
method generates an infinite stream of elements by repeatedly invoking a Supplier Functional InterfaceRead tutorial on Supplier Functional Interface instance passed to it as an input parameter. Stream.generate()
method's signature looks like this -
static<T> Stream<T> generate(Supplier<T> s)
- Only input is an instance of a Supplier Functional Interface of Type T
- Output is a
Stream
of type TLet us now look at how to write the code to create an infinite stream containing random values using
Stream.generate()
and Math.random()
methods.Java 8 code to produce an infinite Stream using Stream.generate()
package com.javabrahman.java8.streams;
import java.util.stream.Stream;
public class InfiniteStreams {
public static void main(String args[]) {
Stream.generate(Math::random)
.limit(5)
.forEach(System.out::println);
}
}
0.8756068395647292 0.7717064739685572 0.8199061254640724 0.6481411588818413 0.8075238156216996
Math.random()
method generates a random value between0.0
and1.0
every time it is called. The function descriptorRead tutorial on Java 8 Function Descriptors ofMath.random()
method matches that of the Supplier Functional Interface, soMath.random()
is passed as an input toStream.generate()
method using its method referenceClick to Read Tutorial on Java 8's Method References -Math::random
.Stream.generate()
method invokesMath.random()
repeatedly to produce an infiniteStream
of values between0.0
and1.0
.- The output stream is limited to
5
elements usingStream.limit()
method. - Output
Stream
is as expected with 5 random values as shown above..
Stream.iterate()
and Stream.generate()
methods with Java 8 code examples to understand their usage.Java 8 Streams API tutorials on JavaBrahman
Streams API - Introduction & BasicsClick to Read tutorial on Streams API Basics Understanding Stream Operations | Intermediate and Terminal OperationsClick to Read Tutorial on Stream Operations Overview Mapping with Streams using map and flatMap methodsClick to Read how Mapping with Java8 Streams works Filtering and Slicing with Streams using filter,distinct,limit,skip methodsClick to Read how Filtering and Slicing with Java8 Streams works Matching with Streams using allMatch,anyMatch,noneMatch methodsClick to Read tutorial on matching with Streams API Stream API's findFirst,findAny methods' tutorialClick to Read tutorial on findFirst() and findAny() methods of Streams API 'Peeking' into a running Stream with Stream.peek() methodClick to Read tutorial on Stream.peek() method Creating Infinite Streams with iterate\generate methodsClick to Read tutorial on Creating Infinite Streams Reducing Streams using Streams.reduce methodClick to Read tutorial on Reducing Streams
Streams API - Introduction & BasicsClick to Read tutorial on Streams API Basics Understanding Stream Operations | Intermediate and Terminal OperationsClick to Read Tutorial on Stream Operations Overview Mapping with Streams using map and flatMap methodsClick to Read how Mapping with Java8 Streams works Filtering and Slicing with Streams using filter,distinct,limit,skip methodsClick to Read how Filtering and Slicing with Java8 Streams works Matching with Streams using allMatch,anyMatch,noneMatch methodsClick to Read tutorial on matching with Streams API Stream API's findFirst,findAny methods' tutorialClick to Read tutorial on findFirst() and findAny() methods of Streams API 'Peeking' into a running Stream with Stream.peek() methodClick to Read tutorial on Stream.peek() method Creating Infinite Streams with iterate\generate methodsClick to Read tutorial on Creating Infinite Streams Reducing Streams using Streams.reduce methodClick to Read tutorial on Reducing Streams