How to generate random numbers in Java
Tuesday, April 15, 2008
Generating random numbers can be useful in many situations. For example, it can be used to determine the value when rolling dice, introduce random movements into character moves in a game, and more.
Note: Technically speaking, when we say “random numbers” here, it actually is pseudo-random numbers, as it is not possible to generate truly random numbers.
There are two common ways to generate random numbers in Java.
One method is to make an instance of a java.util.Random
class and another is to the use the java.lang.Math.random()
method.
This how-to will introduce both.
Using the Random class
First method, we can use the java.util.
Random
class to generate random numbers.
The Random
class is quite versatile.
There are several methods available which return different types.
If you want to produce a random answer for true-false questions, you could use the Random.nextBoolean()
method to get a randomly selected boolean
.
For a full list of the methods available, take a look at the Javadocs for the Random
class.
The following is an example of using the Random.nextInt(int)
method to simulate rolling dice:
import java.util.Random;
/**
* RandomApp demonstrates the use of the Random class to generate
* pseudo-random numbers, simulating a roll of a die.
* @author coobird
*/
public class RandomApp {
public static void main(String[] args) {
// Instantiate a Random object "r"
Random r = new Random();
// Random.nextInt(int) returns a value from 0 (inclusive)
// up to but excluding the int passed into the method.
// (6 is excluded)
int number = r.nextInt(6) + 1;
System.out.println("You rolled a " + number);
}
}
In the example above, we instantiate a Random
object with its default constructor Random()
.
Then, the Random.nextInt(int)
method is called to receive an int
to which 1 is added.
This is because the Random.nextInt(int)
method will return an int
from 0 (inclusive) to the int
that is passed in, which is excluded.
Therefore, calling r.nextInt(6)
will actually return random numbers ranging from 0 to 5.
Since a die has 1 to 6 as its faces, we need to add a 1 to the returned value to end up with a random number ranging between 1 to 6 to be stored in the variable number
.
Seeding Random
The random number generator that the Random
class uses is a pseudo-random number generator.
It is an algorithm that generates numbers in a specified range with (almost) equal probability for any one value in the range.
The details are contained in the Javadoc for the Random
class.
When the pseudo-random number generator sets out to generate a number, it requires a parameter called a “seed” to pass to its generator algorithm. When the same value of the seed is given to the algorithm, it will generate pseudo-random numbers, each value with the same probability of being picked from another. However, the sequence at which those values appear will be the same. Since this is usually not desirable when random numbers are wanted, the seed needs to be changed for each time we want to generate random numbers.
One way to seed the pseudo-number generator is to use the current time as the seed for the generator.
The System.currentTimeMillis()
method returns a long
that can be passed to the Random
object as its seed.
Seeing a Random
object can be done when the object is instantiated or through the Random.setSeed(long)
.
Also, calling the Random()
constructor will generate a Random object that is seeded with a value that will probably differ on each execution.
Following is an example of seeding the Random
object:
import java.util.Random;
/**
* RandomApp2 demonstrates seeding the Random object and how
* that affects the sequence of random numbers that are
* generated.
* @author coobird
*/
public class RandomApp2 {
private static void rollTheDie(Random r) {
// Displays the 10 rolls of the die
System.out.println("Roll the die!");
for (int i = 0; i < 10; i++)
System.out.print((r.nextInt(6) + 1) + ", ");
System.out.println();
}
public static void main(String[] args) {
// Instantiate a Random object, seeded with a value that
// should vary on each execution
Random r = new Random();
// Roll the die.
rollTheDie(r);
// Now, let's seed the Random object with 42, then
// roll the die.
r.setSeed(42);
rollTheDie(r);
// Now, seed with the current system time and roll.
r.setSeed(System.currentTimeMillis());
rollTheDie(r);
}
}
Rolling the die will generate a sequence of 10 random numbers under three different conditions.
Random
object that was instantiated using the default constructorRandom
object seeded usingsetSeed(long)
method called with 42 as argument, andRandom
object seeded with the current system time.
Running the above program once doesn’t quite tell the whole story. When run three times, I had the following output:
First run:
Roll the die!
2, 5, 3, 6, 6, 2, 4, 3, 1, 3,
Roll the die!
3, 4, 1, 3, 1, 2, 6, 3, 2, 6,
Roll the die!
6, 4, 5, 4, 6, 3, 6, 6, 4, 2,
Second run:
Roll the die!
3, 3, 6, 2, 1, 6, 1, 6, 3, 4,
Roll the die!
3, 4, 1, 3, 1, 2, 6, 3, 2, 6,
Roll the die!
5, 4, 5, 2, 6, 2, 2, 1, 5, 3,
Third run:
Roll the die!
5, 6, 1, 5, 3, 5, 4, 5, 5, 6,
Roll the die!
3, 4, 1, 3, 1, 2, 6, 3, 2, 6,
Roll the die!
5, 1, 2, 6, 6, 3, 3, 2, 1, 3,
If you take a look at the second series of “Roll the die!”, you’ll notice that the sequence of random numbers are exactly the same throughout the three executions.
This shows that seeding the Random
pseudo-random number generator will generate the same sequence between executions, and the two other methods used did produce different sequences because they used different seeds on each execution.
Note: There are some misconceptions which lead people to seed a random number generator every time a random number is picked. This probably is not necessary, as by seeding the generator once per execution of a program will already generate a new sequence of random numbers.
Another Method
Another method to generate a random number is to use the Math.random()
method.
The method will return a double
with a range of 0.0 to 1.0.
This method may be easier to use because it doesn’t require that a Random
object is generated and then having to call one of its methods to generate a random number.
However, it is limited because it will only return double
in the range of 0.0
to 1.0
, and by usage, it may require scaling and adjusting the returned value to one’s needs.
The following is the dice program above using the Math.random()
method:
/**
* RandomApp3 demonstrates the use of the Math.random()
* method to generate pseudo-random numbers, simulating
* a roll of a die.
* @author coobird
*/
public class RandomApp3 {
public static void main(String[] args) {
// We don't need to make a Random object
// The Math.random() returns a double between
// 0.0 and 1.0. In order to get an int between
// 1 to 6, the double returned must be multiplied
// by 6, and as before, increased by 1, and
// finally casted to an int.
int number = (int)(Math.random() * 6) + 1;
System.out.println("You rolled a " + number);
}
}
As can be seen, a random number can be obtained in just one line, just by calling one method.
This may be more convenient if the limitations of the Math.random()
does not cause a problem.