In the developer’s world, it is a common task to generate a random number, in a situation like where we need to send an OTP to a user for authentication or need to generate secure SALT which will be used in cryptography, etc. In this Java Random Number generator article, we will learn how to generate random in Java and Generate random numbers in a specific range
What is a Random Number?
A Random number is a number whose values cannot be predicted based on current or past values. The random numbers are calculated based on a starting value which is called a seed. The numbers generated using these methods are not truly random they are pseudorandom as that they produce the same result when the seed is the same and hence extra caution is required while selecting the seed.
Java Random Number Generator
Random number can be generated using the below built-in ways provided by Java.
1. Using Math.random() method
2. Using Random Class
3. Using ThreadLocalRandom
4. Using SecureRandom
5. Using SplittableRandom
6. Apache Commons – RandomSource
1. Using Math.random() method:
Math class of java.util package can be used to generate random number, this method returns double type random numbers in the range 0.0 (included) to 1.0 (not included). Every run generates different random within the range.
package com.javainterviewpoint; public class RandomGenerator1 { public static void main(String[] args) { System.out.println(Math.random()); } }
Output:
Run 1: 0.5845862222795131
Run 2: 0.1579075367108116
Run 3: 0.7426390162202368
2. Using Random nextInt()
The Random class can generate a random number of any type such as int, long, float, double and boolean.
In order to generate a random value all you need to do is create an instance for the Random class and call one of the generator methods nextInt(), nextLong(), nextDouble(), nextFloat(), nextBoolean() or nextGaussian().
java.util.Random class provides us with 2 constructors
- Random() – The seed for this constructor comes from the Operating System (through system time), this constructor sets the seed distinct every time, so that the random number generated will always be unique.
- Random(long seed) – To this constructor, we need to manually pass the seed, so extra precaution has to be taken if we have used same seeds again then the random numbers generated will be reproducible.
package com.javainterviewpoint; import java.util.Random; public class RandomGenerator2 { public static void main(String[] args) { Random random = new Random(); System.out.println("Int random value: "+random.nextInt()); System.out.println("Long random value: "+random.nextLong()); System.out.println("Float random value: "+random.nextFloat()); System.out.println("Double random value: "+random.nextDouble()); System.out.println("Boolean random value: "+random.nextBoolean()); System.out.println("Gaussian random value: "+random.nextGaussian()); } }
Output:
Int random value: 1522322049
Long random value: 6093147356997379110
Float random value: 0.6631488
Double random value: 0.8895098917292387
Boolean random value: true
Gaussian random value: 1.9963614758265926
3. Using ThreadLocalRandom nextInt()
ThreadLocalRandom was introduced in Java 7, ThreadLocalRandom gives better performance and less overhead in a multi-threaded environment. Though Random class instance is also thread-safe concurrent usage will result in contention and poor performance.
The ThreadLocalRandom random number generator is isolated to the current instance, a new instance will be created for each thread with an internally generated seed. ThreadLocalRandom class doesn’t support explicit seeding, unlike Random class, to ensure true randomness.
The current() method returns the instance of the ThreadLocalRandom class and call one of the randon number generator methods nextInt(), nextLong(), nextDouble(), nextFloat(), nextBoolean() or nextGaussian().
package com.javainterviewpoint; import java.util.concurrent.ThreadLocalRandom; public class RandomGenerator3 { public static void main(String[] args) { ThreadLocalRandom threadRandom = ThreadLocalRandom.current(); System.out.println("Int ThreadLocalRandom value: "+threadRandom.nextInt()); System.out.println("Long ThreadLocalRandom value: "+threadRandom.nextLong()); System.out.println("Float ThreadLocalRandom value: "+threadRandom.nextFloat()); System.out.println("Double ThreadLocalRandom value: "+threadRandom.nextDouble()); System.out.println("Boolean ThreadLocalRandom value: "+threadRandom.nextBoolean()); System.out.println("Gaussian ThreadLocalRandom value: "+threadRandom.nextGaussian()); } }
Output:
Int ThreadLocalRandom value: 990106433
Long ThreadLocalRandom value: 8027832646627142177
Float ThreadLocalRandom value: 0.4793735
Double ThreadLocalRandom value: 0.7180076100435611
Boolean ThreadLocalRandom value: false
Gaussian ThreadLocalRandom value: 1.4051837455488967
4. Using SecureRandom
Random class instances are not cryptographically secure, SecureRandom is Cryptographically Secure Pseudo-Random Number Generators (CSPRNG) which can generate a cryptographically secure random number. The SecureRandom is mostly used in the Security algorithm for generating the secret keys.
SecureRandom instance can be obtained in two different ways
1. By calling the no argument constructor
SecureRandom random = new SecureRandom();
2. By calling the getInstance() method
SecureRandom secureRandom = SecureRandom.getInstance(“SHA1PRNG”);
Calling the getInstance() factory method is the preferred way for obtaining the instance of the SecureRandom class, where we will have the ability to specify the pseudorandom number-generation algorithm and optionally the desired provider of the algorithm.
Once we have obtained the instance, all we need to do is just call the random number generator methods such as nextInt(), nextFloat(), nextDouble(), etc.
package com.javainterviewpoint; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; public class RandomGenerator4 { public static void main(String[] args) throws NoSuchAlgorithmException { SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); System.out.println("Int SecureRandom value: " + secureRandom.nextInt()); System.out.println("Long SecureRandom value: " + secureRandom.nextLong()); System.out.println("Float SecureRandom value: " + secureRandom.nextFloat()); System.out.println("Double SecureRandom value: " + secureRandom.nextDouble()); System.out.println("Boolean SecureRandom value: " + secureRandom.nextBoolean()); System.out.println("Gaussian SecureRandom value: " + secureRandom.nextGaussian()); } }
Output:
Int SecureRandom value: 1913474842
Long SecureRandom value: 8268106703555893418
Float SecureRandom value: 0.15969068
Double SecureRandom value: 0.5094652770920555
Boolean SecureRandom value:false
Gaussian SecureRandom value: 2.110809484976118
5. Using SplittableRandom
SplittableRandom is introduced in Java 8, it is a high-performance random number generator but not thread-safe. SplittableRandom can be used with Stream API or Parallel stream which enables us to produce quality pseudorandom numbers. The split() constructs and returns a new SplittableRandom instance that shares no mutable state with the current instance.
Just create a instance for the SplittableRandom class by calling the no argument constructor and call the generator method.
package com.javainterviewpoint; import java.util.SplittableRandom; public class RandomGenerator5 { public static void main(String[] args) { SplittableRandom splittableRandom = new SplittableRandom(); System.out.println(splittableRandom.nextInt()); } }
6. Apache Commons – RandomSource
In order to use the Apache commons-rng third party api [commons-rng-simple.jar, commons-rng-core.jar, commons-rng-client-api.jar] we need to have the below dependencies added in the project.
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-rng-simple</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-rng-core</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-rng-client-api</artifactId>
<version>1.2</version>
</dependency>
RandomSource can be instantiated through the create() factory method, we need to pass implementation as a parameter we have used RandomSource.JDK implementation. List of all the implementations is available here.
Like other Random numbers generator just call one of the generator methods.
package com.javainterviewpoint; import org.apache.commons.rng.UniformRandomProvider; import org.apache.commons.rng.simple.RandomSource; public class RandomGenerator6 { public static void main(String[] args) { UniformRandomProvider random = RandomSource.create(RandomSource.JDK); System.out.println(random.nextInt()); } }
Generate Random Numbers within range
All the above techniques will simply generate random number but there is no range associated with it, let’s now try to generate random numbers within range
1. Using Math.random()
Math.random() generates the random between 0.0 and 1.0 and if suppose you want to generate the random number between 10 and 25, then we need to do the below tweaks.
min + (int) (Math.random() * ((max – min) + 1))
- In order to get the specific range of values, we need to multiply it with the difference range, which will be Math.random() * ( 25 – 10), this would return the values within the range of [0,15] (15 is excluded)
- Now, add the min range, so that the generated random will not be less than min.
min + (Math.random() * (max – min)) —> 10 + (Math.random() * (15))
- Since the max range is excluded we just need to add 1 to make it inclusive.
min + (Math.random() * ((max – min) + 1)) —> 10 + (Math.random() * (16))
- Math.random() generates random as a double value, in order to truncate the decimal part just cast it to int
min + (int) (Math.random() * ((max – min) + 1)) —> 10 + (int) (Math.random() * (16))
The code looks like below
public class RandomGenerator { public static void main(String[] args) { int min = 10; int max = 25; System.out.println(min + (int) (Math.random() * ((max - min) + 1))); } }
Output:
Run 1: 23
Run 2: 11
Run 3: 15
2. Using Random nextInt() method
The nextInt() of Random class has one more variant nextInt(int bound), where we can specify the upper limit, this method returns a pseudorandom between 0 (inclusive) and specified limit (exclusive).
Again a small tweak is needed.
min + random.nextInt(max – min + 1)
- Difference between min and max limit and add 1 (for including the upper range) and pass it to the nextInt() method, this will return the values within the range of [0, 16]
random.nextInt(max – min + 1) —> random.nextInt(16)
- Just add the min range, so that the random value will not be less than min range.
min + random.nextInt(max – min + 1) —> 10 + random.nextInt(16)
import java.util.Random; public class RandomGenerator { public static void main(String[] args) { int min = 10; int max = 25; Random random = new Random(); System.out.println(min + random.nextInt(max - min + 1)); } }
3. Using Random ints() method
ints() method was introduced to Random Class in Java 8, this method returns unlimited stream of pseudorandom int values.
import java.util.Arrays; import java.util.Random; public class RandomGenerator { public static void main(String[] args) { int min = 10; int max = 25; Random random = new Random(); int[] numbers = new Random().ints(min,max+1).limit(10).toArray(); System.out.println(Arrays.toString(numbers)); } }
Since the ints() method produces unlimited stream of random numbers, we might encounter OutOfMemoryError as the heap space will be full, with this in mind be sure to use the limit() method which limits the number of pseudorandom generated.
4. Using ThreadLocalRandom nextInt() method
ThreadLocalRandom class nextInt() method has the ability to take the min and max range.
public int nextInt(int least, int bound)
least – min range (inclusive)
bound – max range (exclusive)
import java.util.concurrent.ThreadLocalRandom; public class RandomGenerator { public static void main(String[] args) { int min = 10; int max = 25; ThreadLocalRandom threadRandom = ThreadLocalRandom.current(); System.out.println((int)threadRandom.nextDouble(min, max+1)); } }
5. Using RandomUtils
We should be having the Apache commons-lang3.jar in the classpath in order to use the RandomUtils.
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
The nextInt() method generates int random values, where the lower range is inclusive and upper range is exclusive.
import org.apache.commons.lang3.RandomUtils; public class RandomGenerator { public static void main(String[] args) { int min = 10; int max = 25; System.out.println(RandomUtils.nextInt(min, max+1)); } }
6. Using RandomDataGenerator
RandomDataGenerator needs Apache commons-math3.jar in the classpath. The RandomDataGenerator by default uses Well19937c generator for generating random numbers.
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
import org.apache.commons.math3.random.RandomDataGenerator; public class RandomGenerator { public static void main(String[] args) { // Both Upper and Lower are included RandomDataGenerator random = new RandomDataGenerator(); System.out.println(random.nextInt(5, 10)); } }
Hope i have covered most of Java Random Number Generator, Do let me know if anything can be added.
Happy Learning !! 🙂
Leave a Reply