Generating random numbers in Java is a common task.
It’s frequently used in gambling, cryptography, statistical sampling and other areas where you need to simulate unpredictable behavior.
I’ll explain to you how to create random number generator and show few a little bit different ways how to do that.
How To Generate Random Range in Java
Usually, we want to generate a random integer in range.
That means we should create a function, that will generate a random number between min and max value.
Java Core provides 5 classes to do that:
- java.util.Random
- java.lang.Math
- java.util.concurrent.ThreadLocalRandom
- java.security.SecureRandom
- java.util.SplittableRandom
You can use libraries as well:
- org.apache.commons.lang3.RandomUtils
- org.apache.commons.math3.random.RandomDataGenerator
What to use?
Since Java 8 I would recommend SplittableRandom
, in all other cases ThreadLocaleRandom
is your the best choice.
SplittableRandom
is not thread-safe, that’s why it’s faster + it can be used with a stream API and even parallel streams + it generates more quality pseudorandom numbers.
Random
class has 2 little problems:
- it’s not cryptographically secure.
- it’s thread-safe, but the concurrent use of the same
java.util.Random
instance across threads may encounter contention and consequent poor performance.
ThreadLocaleRandom
doesn’t have the 2nd problem but isn’t cryptographically secure as well.
If you need a cryptographically secure random generator – use java.security.SecureRandom
.
Math.random()
generates a random double number and uses Random class internally to do that.
Let’s take a look at code examples.
Random
java.util.Random
class has a lot of methods, but nextInt() is the most popular. That’s why I’ll show you an example of it.
That’s why I’ll show you an example of it:
private static final Random RANDOM = new Random();
public static int random(int min, int max) {
return RANDOM.nextInt(max) + min;
}
Our random(min, max) method will generate a pseudorandom number in a range between [min, max).
Min value will be inclusive and max will be exclusive.
Math.random()
This method generates a random double number. Internally on the first call, it creates an instance of java.util.Random
class and uses it to generate a value.
It’s the same if you call java.util.Random.nextDouble()
.
Example:
public static int random(int min, int max) {
return (int) (min + (Math.random() * (max - min)));
}
The method will generate a pseudorandom integer from min (including) to max (excluding).
ThreadLocalRandom
A random number generator isolated to the current thread, so you can use it in the concurrent environment without any problems.
Since Java 8 it’s protected with @Contended annotation against false sharing.
Example:
public static int random(int min, int max) {
return ThreadLocalRandom.current().nextInt(min, max);
}
One more benefit – ThreadLocaleRandom class provides commonly used method to generate a number in a range, just specify min and max values and that’s it.
SecureRandom
Provides cryptographically strong random number generator.
It passes statistical random generator tests.
Usually, SecureRandom is used in the following way:
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);
By default SecureRandom class uses PRNG algorithm.
It could be switched like this:
SecureRandom.getInstance(algorithm)
SplittableRandom
SplittableRandom
is a really interesting class, that was added in the scope of Java 8.
The differences with a Random
class are:
- it passes a Diehard test, that means it can generate more quality pseudorandom numbers.
- it’s not thread-safe, but faster than
Random
. - method split creates a new SplittableRandom instance that shares no mutable state with the current instance. It’s useful for parallel streams.
- it doesn’t extend a
Random
class likeSecureRandom
andThreadLocalRandom
.
Let’s take a look at code examples.
The most common task is to generate a random number in the range:
new SplittableRandom().nextInt(1, 5)
Generate an array of random ints in the range:
new SplittableRandom().ints(5, 1, 10).toArray()
As you see this class has stream-friendly API. Personally, I really like it!
Since Java 10 was added SplittableRandom.nextBytes
, so you can use it as well.
RandomUtils
It’s just a wrapper for example, that I provided for a java.util.Random
class.
To use RandomUtils you should add maven dependency:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
Method signature looks like this:
public static int nextInt(final int startInclusive, final int endExclusive)
RandomUtils provides methods to generate double, float, long and bytes as well.
RandomDataGenerator
RandomDataGenerator uses WELL19937c pseudo-random number generator to generate the data.
You need to include commons-math3
dependency to your pom.xml
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6</version>
</dependency>
A method that generates an integer value looks like that:
public int nextInt(final int lower, final int upper)
It works in the same way as previous code examples.
Library provides a big amount of methods to generate a different kind of data.
It could be useful for advanced use cases.