Generate Infinite Stream of Doubles in Java
This article provides an overview of how to generate an infinite stream of doubles in Java. An infinite stream is a sequential, unordered stream that doesn’t end.
Until now, many of we might have operated only on the finite streams. If a stream in Java is not properly bounded, then calling any terminal operation upon it may cause the program to enter into an infinite loop. We should always ensure that a stream is properly bounded. If not, then we should limit the stream only to return the first few terms from the beginning. Let’s now discuss how to generate an infinite stream of doubles in Java:
1. Using DoubleStream.iterate() method
A simple way is using the DoubleStream.iterate() method that takes a seed value and a method that generates the next value based on the previous one. It accepts two parameters: a seed which would be the first term in the stream, and a method to be applied to the previous term of the stream to produce the value of the next term in the stream. For example, the following code generates an infinite stream of doubles starting from 0.0 and increasing by 0.01:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import java.util.stream.DoubleStream; class Main { public static void main(String[] args) { DoubleStream.iterate(0.0, i -> i + 0.01) .forEach(System.out::println); // 0.0 // 0.01 // 0.02 // 0.03 // 0.04 // … } } |
2. Using DoubleStream.generate() method
Another alternative is to use the DoubleStream.generate() method that returns an infinite stream. It accepts a Supplier<T>, rather than a method, to generate a value each time it is invoked. Several suppliers are available in Java that can be passed as a parameter to the DoubleStream.generate() method to generate an infinite stream of doubles. For example, the following code generates an infinite stream of random doubles between 0.0 (included) and 1.0 (excluded) using Math.random() method:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import java.util.stream.DoubleStream; class Main { public static void main(String[] args) { DoubleStream.generate(Math::random) .forEach(System.out::println); // [0, 1) // 0.4622997342667172 // 0.4742599881203049 // 0.2919236612858549 // 0.48148801463431334 // 0.47444132067895706 // … } } |
We can also use the Random.nextDouble() or the ThreadLocalRandom.current().nextDouble() method as a supplier for the DoubleStream.generate(). Both methods returns the next pseudorandom, uniformly distributed double value from the range 0.0 (inclusive) to 1.0 (exclusive). For example:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import java.util.Random; import java.util.stream.DoubleStream; class Main { public static void main(String[] args) { DoubleStream.generate(new Random()::nextDouble) .forEach(System.out::println); // [0, 1) // 0.6638624509269384 // 0.5333512669211747 // 0.3568920248020473 // 0.4211416733263408 // 0.3292053879479139 // … } } |
Finally, we can also use the PrimitiveIterator.OfDouble().nextDouble() method as a supplier for the DoubleStream.generate() method to generate new values for the stream. This method can return the next double value from the iterator. For example, we can create a custom PrimitiveIterator.OfDouble() that increments a double value by 0.01 each time, and then use it to generate an infinite stream of doubles as follows:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import java.util.PrimitiveIterator; import java.util.stream.DoubleStream; class Main { public static void main(String[] args) { PrimitiveIterator.OfDouble itr = new PrimitiveIterator.OfDouble() { private double i = 0.0; @Override public double nextDouble() { return i = i + 0.01; } @Override public boolean hasNext() { return (i < Double.MAX_VALUE); } }; DoubleStream.generate(itr::nextDouble) .forEach(System.out::println); // 0.01 // 0.02 // 0.03 // 0.04 // 0.05 // … } } |
3. Using Random.doubles() method
Finally, we can also use the Random.doubles() method to generate an infinite stream of pseudorandom double values between 0 (inclusive) and 1 (exclusive). For example, the following code generates an infinite stream of random doubles greater than or equal to 0.0 and less than 1.0:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import java.util.Random; class Main { public static void main(String[] args) { new Random().doubles().limit(5) .forEach(System.out::println); // 0.7916396973190407 // 0.5003418018630583 // 0.7478198063524019 // 0.6688739450377388 // 0.2957157225321535 // … } } |
The Random.doubles() method is overloaded to accept a range for generating the pseudorandom double values. For example, the following code sets the range of returned random values to [1, 2):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import java.util.Random; class Main { public static void main(String[] args) { new Random().doubles(1, 2) .forEach(System.out::println); // [1, 2) // 1.802479194437851 // 1.9391095775982015 // 1.1099686485195792 // 1.7493104034629803 // 1.7298380806790292 // … } } |
Note that all above methods will return an infinite stream, which means that they will never terminate unless we limit them with a terminal operation such as limit(), takeWhile(), or findFirst(). Otherwise, our program may enter into an infinite loop and consume a lot of memory. We should always ensure that our stream is properly bounded or use a short-circuiting operation to avoid this problem.
Exercise: Generate an infinite stream of integers in Java.
That’s all about generating an infinite stream of doubles in Java.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)