The Random Class
The java.util.Random class is used to generate a stream of pseudorandom numbers.
While the Math.random() method (from the java.lang package) is great for quickly generating random double values between 0.0 and 1.0, the Random class provides a much more flexible and powerful API for generating random integers, booleans, floats, and bytes.
Creating a Random Object
To use the Random class, you must first create an instance of it.
import java.util.Random;
public class LabRandom1 {
public static void main(String[] args) {
// Create a new Random object
Random random = new Random();
// Generate a random boolean
boolean randBool = random.nextBoolean();
System.out.println("Random Boolean: " + randBool);
// Generate a random double (between 0.0 and 1.0)
double randDouble = random.nextDouble();
System.out.println("Random Double: " + randDouble);
}
}
Generating Random Integers
The most common use case for the Random class is generating random integers.
1. Unbounded Integers
If you call nextInt() without arguments, it generates a random integer across the entire range of possible int values (from -2,147,483,648 to 2,147,483,647).
int anyInt = random.nextInt();
2. Bounded Integers
If you pass an integer argument bound to nextInt(int bound), it generates a random number between 0 (inclusive) and the specified bound (exclusive).
public class LabRandom2 {
public static void main(String[] args) {
Random random = new Random();
// Generate a random number between 0 and 9
int randInt1 = random.nextInt(10);
System.out.println("Random number (0 to 9): " + randInt1);
// Generate a random number between 1 and 6 (like a dice roll)
int diceRoll = random.nextInt(6) + 1;
System.out.println("Dice Roll: " + diceRoll);
}
}
Working with Seeds
Pseudorandom number generators work by starting with a seed value and applying a mathematical formula to generate the next number.
If you create two Random objects with the exact same seed, they will generate the exact same sequence of numbers. This is incredibly useful for testing or scenarios where you need predictable randomness.
public class LabRandom3 {
public static void main(String[] args) {
// Both Random objects use the same seed: 42
Random random1 = new Random(42);
Random random2 = new Random(42);
System.out.println("Generator 1: " + random1.nextInt(100));
System.out.println("Generator 2: " + random2.nextInt(100));
System.out.println("Generator 1: " + random1.nextInt(100));
System.out.println("Generator 2: " + random2.nextInt(100));
}
}
Output:
Generator 1: 30
Generator 2: 30
Generator 1: 63
Generator 2: 63
[!NOTE] When you use the default constructor
new Random(), Java automatically seeds it with a value that is very likely to be distinct from any other invocation (usually based on the current system time in nanoseconds).