Generating Random Numbers
A ludo game rolls a die. A quiz app shuffles its questions. A bank sends a one-time password (OTP). All of them need random numbers, but not all random numbers are equal: a dice game just needs variety, while an OTP must be impossible to guess. Java offers a tool for each job, and choosing the right one matters.
Four Tools
| Tool | Use for | Example |
|---|---|---|
Math.random() | Quick experiments | a double from 0.0 (inclusive) to 1.0 (exclusive) |
java.util.Random | Games, simulations, repeatable tests with a seed | new Random(42).nextInt(1, 7) |
ThreadLocalRandom | Everyday ranges, fast, safe with many threads | ThreadLocalRandom.current().nextInt(1, 7) |
java.security.SecureRandom | OTPs, passwords, tokens: anything secret | new SecureRandom().nextInt(1_000_000) |
Rolling a Die
import java.util.concurrent.ThreadLocalRandom;
public class Dice {
public static void main(String[] args) {
int die = ThreadLocalRandom.current().nextInt(1, 7);
double chance = Math.random();
System.out.println("You rolled " + die);
System.out.printf("Random fraction: %.3f%n", chance);
}
}You rolled 4
Random fraction: 0.712The output changes on every run; that's the point. Math.random() gives a double in [0.0, 1.0). To turn it into a range, the classic formula is (int) (Math.random() * 6) + 1 for 1 to 6, but nextInt(1, 7) says the same thing more clearly.
Repeatable Randomness with a Seed
A Random created with a seed produces the same sequence every time. That sounds odd, but it's exactly what tests and simulations need:
import java.util.Random;
public class Seeded {
public static void main(String[] args) {
Random dice = new Random(42);
for (int i = 0; i < 5; i++) {
System.out.print(dice.nextInt(1, 7) + " ");
}
System.out.println();
}
}3 4 1 3 1How it works
- Line 5 creates a generator with seed 42.
- Line 7 rolls five dice. Run it again, on any computer, and you get 3 4 1 3 1 again.
- Without a seed (
new Random()), the sequence is different each run.
Try it yourself: change the seed to 7. Does the sequence change? Does it stay the same across runs?
A Six-Digit OTP
import java.security.SecureRandom;
public class Otp {
public static void main(String[] args) {
SecureRandom secure = new SecureRandom();
int otp = secure.nextInt(1_000_000);
System.out.printf("Your OTP is %06d%n", otp);
}
}Your OTP is 048213nextInt(1_000_000) gives 0 to 999,999, and %06d pads it to six digits with leading zeros, so 48213 prints as 048213.
Common Mistakes
Off-by-one ranges. nextInt(1, 6) never returns 6. The upper bound is exclusive.
Creating a new Random inside a loop. It's wasteful; create one and reuse it, or use ThreadLocalRandom.current().
Using a fixed seed in production. Seeds are for tests. A game with new Random(42) deals the same cards every time.
Practice
- Easy: Simulate tossing a coin 10 times and count heads and tails.
- Harder: Shuffle an array of five names (Navika, Srihitha, Advitha and two more) using the Fisher-Yates method: for
ifrom the end down to 1, swap elementiwith a random element from 0 toi.
Key Takeaways
Was this tutorial helpful?