java.util.Random in Java 8

One of the neat features of java.util.Random class in Java 8 is that it has been retrofitted to now return a random Stream of numbers.

For eg, to generate an infinite stream of random doubles between 0(inclusive) and 1(exclusive):
 
 
 
 
 
 
 

Random random = new Random();
DoubleStream doubleStream = random.doubles();

or to generate an infinite stream of integers between 0(inclusive) and 100(exclusive):

Random random = new Random();
IntStream intStream = random.ints(0, 100);

So what can this infinite random stream be used for, I will demonstrate a few scenarios, do keep in mind though that since this is an infinite stream, any terminal operations has to be done once the stream has been made limited in some way, otherwise the operation will not terminate!

For eg. to get a stream of 10 random integers and print them:

intStream.limit(10).forEach(System.out::println);

Or to generate a list of 100 random integers :

List<Integer> randomBetween0And99 = intStream
                                       .limit(100)
                                       .boxed()
                                       .collect(Collectors.toList());

For gaussian pseudo-random values, there is no stream equivalent of random.doubles(), however it is easy to come up with one with the facility that Java 8 provides:

Random random = new Random();
DoubleStream gaussianStream = Stream.generate(random::nextGaussian).mapToDouble(e -> e);

Here, I am using the Stream.generate api call passing in a Supplier which generates the next gaussian with the already available method in Random class.

So now to do something a little more interesting with the stream of pseudo-random doubles and the stream of Gaussian pseudo-random doubles, what I want to do is to get the distribution of doubles for each of these two streams, the expectation is that the distribution when plotted should be uniformly distributed for pseudo-random doubles and should be normal distributed for Gaussian pseudo-random doubles.

In the following code, I am generating such a distribution for a million pseudo-random values, this uses a lot of facilities provided by the new Java 8 Streams API:

Random random = new Random();
DoubleStream doubleStream = random.doubles(-1.0, 1.0);
LinkedHashMap<Range, Integer> rangeCountMap = doubleStream.limit(1000000)
        .boxed()
        .map(Ranges::of)
        .collect(Ranges::emptyRangeCountMap, (m, e) -> m.put(e, m.get(e) + 1), Ranges::mergeRangeCountMaps);

rangeCountMap.forEach((k, v) -> System.out.println(k.from() + "\t" + v));

and this code spits out data along these lines:

-1	49730
-0.9	49931
-0.8	50057
-0.7	50060
-0.6	49963
-0.5	50159
-0.4	49921
-0.3	49962
-0.2	50231
-0.1	49658
0	50177
0.1	49861
0.2	49947
0.3	50157
0.4	50414
0.5	50006
0.6	50038
0.7	49962
0.8	50071
0.9	49695

and similarly generating a distribution for a million Gaussian pseudo-random values:

Random random = new Random();
DoubleStream gaussianStream = Stream.generate(random::nextGaussian).mapToDouble(e -> e);
LinkedHashMap<Range, Integer> gaussianRangeCountMap =
        gaussianStream
                .filter(e -> (e >= -1.0 && e < 1.0))
                .limit(1000000)
                .boxed()
                .map(Ranges::of)
                .collect(Ranges::emptyRangeCountMap, (m, e) -> m.put(e, m.get(e) + 1), Ranges::mergeRangeCountMaps);

gaussianRangeCountMap.forEach((k, v) -> System.out.println(k.from() + "\t" + v));

Plotting the data gives the expected result:

For a pseudo-random Data:

pseudorandom

And for Gaussian Data:

gaussian

  • Complete code is available in a gist here – https://gist.github.com/bijukunjummen/8129250

 

Reference: java.util.Random in Java 8 from our JCG partner Biju Kunjummen at the all and sundry blog.
Related Whitepaper:

Bulletproof Java Code: A Practical Strategy for Developing Functional, Reliable, and Secure Java Code

Use Java? If you do, you know that Java software can be used to drive application logic of Web services or Web applications. Perhaps you use it for desktop applications? Or, embedded devices? Whatever your use of Java code, functional errors are the enemy!

To combat this enemy, your team might already perform functional testing. Even so, you're taking significant risks if you have not yet implemented a comprehensive team-wide quality management strategy. Such a strategy alleviates reliability, security, and performance problems to ensure that your code is free of functionality errors.Read this article to learn about this simple four-step strategy that is proven to make Java code more reliable, more secure, and easier to maintain.

Get it Now!  

Leave a Reply


six + = 9



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books