Friday, June 30, 2023

Stop Newing a Random - Introducing Java's Improved RandomGenerator

4 min read
(Updated: Friday, June 30, 2023)

1. Introduction

Randomness plays a critical role in various aspects of computer programming, from gaming and simulations, to cryptography and statistical analysis, and so forth.

Java has always provided ways to generate random numbers, such as the java.util.Random class. On top of that, with the introduction of the RandomGenerator interface in Java 17, the language takes a significant step forward in improving the efficiency and flexibility of random number generation.

In this blog post, we'll explore the new RandomGenerator interface, examine its real-world applications, compare it to prior Java versions, and draw conclusions about its potential impact.

2. Real-world application

Consider a simple lottery application that randomly selects a set of non-repeating numbers within a specified range. Here's an example using the new RandomGenerator interface:

Java
import java.util.stream.Collectors;
import java.util.Set;
import java.util.Random;
import jdk.random.RandomGenerator;
import jdk.random.RandomGeneratorFactory;

public class Lottery {
    public static void main(String[] args) {
        RandomGeneratorFactory<RandomGenerator> factory = RandomGeneratorFactory.of("L64X128MixRandom");
        RandomGenerator rng = factory.create();

        int lowerBound = 1;
        int upperBound = 50;
        int numPicks = 6;
        Set<Integer> winningNumbers = rng.ints(lowerBound, upperBound + 1)
                                        .distinct()
                                        .limit(numPicks)
                                        .boxed()
                                        .collect(Collectors.toSet());

        System.out.println("Winning numbers: " + winningNumbers);
    }
}

3. "Good old" days

Before the introduction of RandomGenerator, the most common approach to generating random numbers in Java was using the java.util.Random or java.util.concurrent.ThreadLocalRandom classes. Here's the lottery application example implemented using java.util.Random:

Java
import java.util.stream.Collectors;
import java.util.Set;
import java.util.Random;

public class Lottery {
    public static void main(String[] args) {
        Random random = new Random();

        int lowerBound = 1;
        int upperBound = 50;
        int numPicks = 6;
        //...
    }
}

Now I just have to say, please don't use this anymore!

4. Why use RandomGenerator?

While the code differences between the two examples may appear subtle, the underlying improvements offered by RandomGenerator are significant:

  1. Algorithm Selection: The new RandomGenerator interface allows developers to choose from a variety of random number generation algorithms, offering improved performance and quality tailored to specific use cases.
  2. Factory Pattern: The RandomGeneratorFactory class provides a clean way to create instances of RandomGenerator, making it easier to switch between algorithms without modifying the code extensively.
  3. Stream API Integration: The RandomGenerator interface seamlessly integrates with Java's Stream API, simplifying the process of generating random numbers and enabling a more functional programming style.

5. One more thing

The RandomGenerator interface in Java 17 provides access to several high-quality random number generation algorithms that offer good performance and follow best practices. Some of these well-known algorithms include:

  1. L64X128MixRandom: This is a 64-bit generator with a 128-bit state, designed to have a fast mixing of its state. It is suitable for most applications that require a good balance between performance and quality.
  2. L128X256MixRandom: This is a 128-bit generator with a 256-bit state, providing a stronger mixing of its state and improved statistical properties. It is suitable for applications that require higher-quality random numbers or larger state sizes, such as simulations or machine learning algorithms.
  3. Xoroshiro128Plus: This is a 128-bit generator with a 128-bit state, based on xorshift operations and a rotation. It offers good performance and quality while being relatively simple to implement. However, it might not be suitable for applications that require high-quality random numbers with an extremely long period.
  4. Xoshiro256Plus: This is a 256-bit generator with a 256-bit state, based on xorshift operations and a rotation. It provides better quality random numbers than Xoroshiro128Plus while maintaining good performance. This generator is suitable for a wide range of applications, including simulations, gaming, and cryptography.
  5. SplittableRandom: This generator is specifically designed for concurrent usage in parallel algorithms. It allows for efficient splitting of its state, enabling the creation of new random number generators for use in separate threads. This is particularly useful in applications that require high-performance parallel random number generation.

When using the RandomGeneratorFactory class, you can create instances of these algorithms by specifying their names, like this:

Java
RandomGeneratorFactory<RandomGenerator> factory = RandomGeneratorFactory.of("L64X128MixRandom");
RandomGenerator rng = factory.create();

And, the power is in your hands!

6. Conclusion

Java 17's improved RandomGenerator interface provides developers with a powerful, flexible, and efficient way to generate random numbers for various applications.

By offering a choice of algorithms and better integration with the Stream API, RandomGenerator significantly enhances the random number generation capabilities in Java compared to prior versions. Give it a try!

You might want to check these out ↘

How Your Database Stands Up to the Ultimate Reliability Check: ACID rules

How Your Database Stands Up to the Ultimate Reliability Check: ACID rules

For IT professionals in database management, grasping the core principles that protect our digital transactions is essential. Today, we're exploring the ACID model, a pivotal framework for ensuring transaction reliability and security. This goes beyond mere theoretical knowledge; it's vital for the smooth operation of diverse systems, from financial processes to social media platforms. We'll delve into the ACID principles and their critical role in real-world applications.
Convert String to Date: The Java Ways

Convert String to Date: The Java Ways

Converting strings to dates in programming is a common task that's more complex than it seems. This challenge is rooted in the wide range of date formats and the specifics of time zones. Converting a String to a Date in Java can be done in several ways, depending on the Java version you're using and whether you are incorporating external libraries. Below are the primary methods used in different versions of Java and through some commonly used external libraries.
Cookbook: How to Effectively Revert a Git Commit

Cookbook: How to Effectively Revert a Git Commit

As a software engineer, encountering situations where recent changes need to be undone is not uncommon. It may be due to errors, or in some cases just need a significant rework. When such scenarios arise while using Git as your version control system, there’s a few approaches that can help revert those changes effectively. Let’s take a closer look.
Technology
Trending
Contact Us

Stay ahead of the curve
on software insights and technology trends.