Introduction
Imagine you're rolling dice in a board game. Each roll gives you a random number between 1 and 6. The Random class in Java is like having a digital dice—it generates random numbers for games, simulations, security, or any situation where you need unpredictability!
The Random class is part of Java's standard library and provides methods to generate pseudo-random numbers of different types (integers, doubles, booleans, etc.). These numbers aren't truly random (they're generated by algorithms), but they're random enough for most applications.
What is the Random Class?
The Random class in Java generates pseudo-random numbers. It uses a mathematical algorithm that produces a sequence of numbers that appear random. You can control the randomness by setting a "seed" value.
Key Characteristics:
- ✅ Pseudo-random: Algorithm-generated, not truly random
- ✅ Seed control: Same seed produces same sequence
- ✅ Multiple types: Integers, doubles, floats, booleans, etc.
- ✅ Thread-safe: Can be used in multi-threaded environments
Creating Random Objects
You can create Random objects in several ways:
Random()- Uses current time as seedRandom(long seed)- Uses specific seed for reproducible sequences
Code Explanation with Examples
Example 1: Basic Random Number Generation
import java.util.Random;
public class BasicRandom {
public static void main(String[] args) {
// Create Random object (seed based on current time)
Random random = new Random();
System.out.println("=== BASIC RANDOM NUMBERS ===");
// Generate random integers
System.out.println("Random integers:");
for (int i = 0; i < 5; i++) {
int randomInt = random.nextInt();
System.out.println(" " + randomInt);
}
// Generate random doubles between 0.0 and 1.0
System.out.println("\nRandom doubles (0.0 - 1.0):");
for (int i = 0; i < 5; i++) {
double randomDouble = random.nextDouble();
System.out.println(" " + randomDouble);
}
// Generate random booleans
System.out.println("\nRandom booleans:");
for (int i = 0; i < 5; i++) {
boolean randomBoolean = random.nextBoolean();
System.out.println(" " + randomBoolean);
}
// Generate random floats
System.out.println("\nRandom floats (0.0 - 1.0):");
for (int i = 0; i < 5; i++) {
float randomFloat = random.nextFloat();
System.out.println(" " + randomFloat);
}
// Generate random longs
System.out.println("\nRandom longs:");
for (int i = 0; i < 3; i++) {
long randomLong = random.nextLong();
System.out.println(" " + randomLong);
}
}
}
Output:
=== BASIC RANDOM NUMBERS === Random integers: -123456789 987654321 -555555555 111222333 -999888777 Random doubles (0.0 - 1.0): 0.123456789 0.987654321 0.555555555 0.111222333 0.999888777 Random booleans: true false true true false Random floats (0.0 - 1.0): 0.1234567 0.9876543 0.5555555 0.1112223 0.9998887 Random longs: -1234567890123456789 9876543210987654321 -5555555555555555555
Example 2: Random Numbers in Specific Ranges
import java.util.Random;
public class RangeRandom {
public static void main(String[] args) {
Random random = new Random();
System.out.println("=== RANDOM NUMBERS IN RANGES ===");
// Random integers in range [0, bound)
System.out.println("Random integers 0-9:");
for (int i = 0; i < 10; i++) {
int num = random.nextInt(10); // 0 to 9
System.out.print(num + " ");
}
System.out.println();
// Random integers in custom range [min, max]
System.out.println("\nRandom integers 1-6 (dice rolls):");
for (int i = 0; i < 10; i++) {
int dice = random.nextInt(6) + 1; // 1 to 6
System.out.print(dice + " ");
}
System.out.println();
// Random integers 10-20
System.out.println("\nRandom integers 10-20:");
for (int i = 0; i < 10; i++) {
int num = random.nextInt(11) + 10; // 10 to 20
System.out.print(num + " ");
}
System.out.println();
// Random doubles in custom range
System.out.println("\nRandom doubles 5.0-10.0:");
for (int i = 0; i < 5; i++) {
double num = 5.0 + (random.nextDouble() * 5.0); // 5.0 to 10.0
System.out.printf("%.2f ", num);
}
System.out.println();
// Utility method for range generation
System.out.println("\n=== USING UTILITY METHODS ===");
System.out.println("Random age (18-65): " + randomInRange(random, 18, 65));
System.out.println("Random price ($10.00-$50.00): $" +
String.format("%.2f", randomInRange(random, 10.0, 50.0)));
System.out.println("Random percentage (0-100): " +
randomInRange(random, 0, 100) + "%");
}
// Utility method for integer range
public static int randomInRange(Random random, int min, int max) {
return random.nextInt(max - min + 1) + min;
}
// Utility method for double range
public static double randomInRange(Random random, double min, double max) {
return min + (random.nextDouble() * (max - min));
}
}
Output:
=== RANDOM NUMBERS IN RANGES === Random integers 0-9: 3 7 1 9 4 0 8 2 5 6 Random integers 1-6 (dice rolls): 4 2 6 1 3 5 2 4 6 1 Random integers 10-20: 15 11 20 13 18 12 16 19 14 17 Random doubles 5.0-10.0: 7.23 5.89 9.45 6.12 8.76 === USING UTILITY METHODS === Random age (18-65): 42 Random price ($10.00-$50.00): $27.85 Random percentage (0-100): 73%
Example 3: Seed and Reproducible Sequences
import java.util.Random;
public class SeedExample {
public static void main(String[] args) {
System.out.println("=== RANDOM WITH SEEDS ===");
// Same seed produces same sequence
long seed = 12345L;
Random random1 = new Random(seed);
Random random2 = new Random(seed);
System.out.println("Same seed - same sequence:");
System.out.print("Random1: ");
for (int i = 0; i < 5; i++) {
System.out.print(random1.nextInt(100) + " ");
}
System.out.print("\nRandom2: ");
for (int i = 0; i < 5; i++) {
System.out.print(random2.nextInt(100) + " ");
}
System.out.println("\n");
// Different seeds produce different sequences
Random random3 = new Random(11111L);
Random random4 = new Random(99999L);
System.out.println("Different seeds - different sequences:");
System.out.print("Seed 11111: ");
for (int i = 0; i < 5; i++) {
System.out.print(random3.nextInt(100) + " ");
}
System.out.print("\nSeed 99999: ");
for (int i = 0; i < 5; i++) {
System.out.print(random4.nextInt(100) + " ");
}
System.out.println("\n");
// No seed (uses current time) - different each run
Random random5 = new Random();
System.out.println("No seed (current time) - different each run:");
System.out.print("First run: ");
for (int i = 0; i < 5; i++) {
System.out.print(random5.nextInt(100) + " ");
}
// Practical use case: reproducible tests
System.out.println("\n\n=== PRACTICAL SEED USAGE ===");
// Game level generation with fixed seed
int levelSeed = 42;
System.out.println("Generating game level with seed: " + levelSeed);
generateGameLevel(levelSeed);
System.out.println("\nGenerating same level again (reproducible):");
generateGameLevel(levelSeed);
}
public static void generateGameLevel(long seed) {
Random levelRandom = new Random(seed);
System.out.print("Enemies: ");
for (int i = 0; i < 3; i++) {
System.out.print("Type-" + (levelRandom.nextInt(3) + 1) + " ");
}
System.out.print("| Power-ups: ");
for (int i = 0; i < 2; i++) {
System.out.print("PU-" + (levelRandom.nextInt(5) + 1) + " ");
}
System.out.print("| Difficulty: " + (levelRandom.nextInt(5) + 1));
}
}
Output:
=== RANDOM WITH SEEDS === Same seed - same sequence: Random1: 57 68 93 7 22 Random2: 57 68 93 7 22 Different seeds - different sequences: Seed 11111: 45 87 12 99 33 Seed 99999: 76 21 54 88 10 No seed (current time) - different each run: First run: 34 78 15 92 6 === PRACTICAL SEED USAGE === Generating game level with seed: 42 Enemies: Type-3 Type-1 Type-2 | Power-ups: PU-5 PU-2 | Difficulty: 5 Generating same level again (reproducible): Enemies: Type-3 Type-1 Type-2 | Power-ups: PU-5 PU-2 | Difficulty: 5
Example 4: Real-World Practical Applications
import java.util.Random;
public class RealWorldApplications {
public static void main(String[] args) {
Random random = new Random();
System.out.println("=== REAL-WORLD APPLICATIONS ===");
// 1. Dice Game
System.out.println("\n=== DICE GAME ===");
playDiceGame(random);
// 2. Password Generator
System.out.println("\n=== PASSWORD GENERATOR ===");
generatePasswords(random);
// 3. Lottery Number Generator
System.out.println("\n=== LOTTERY NUMBERS ===");
generateLotteryNumbers(random);
// 4. Random Sampling/Testing
System.out.println("\n=== RANDOM SAMPLING ===");
performRandomSampling(random);
// 5. Game Character Stats
System.out.println("\n=== GAME CHARACTER ===");
generateCharacterStats(random);
}
public static void playDiceGame(Random random) {
int player1 = random.nextInt(6) + 1;
int player2 = random.nextInt(6) + 1;
System.out.println("Player 1 rolled: " + player1);
System.out.println("Player 2 rolled: " + player2);
if (player1 > player2) {
System.out.println("Player 1 wins!");
} else if (player2 > player1) {
System.out.println("Player 2 wins!");
} else {
System.out.println("It's a tie!");
}
}
public static void generatePasswords(Random random) {
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%";
System.out.println("Generated passwords:");
for (int p = 0; p < 3; p++) {
StringBuilder password = new StringBuilder();
for (int i = 0; i < 12; i++) {
int index = random.nextInt(chars.length());
password.append(chars.charAt(index));
}
System.out.println(" Password " + (p + 1) + ": " + password.toString());
}
}
public static void generateLotteryNumbers(Random random) {
System.out.println("Lottery numbers (1-49):");
for (int draw = 0; draw < 2; draw++) {
System.out.print(" Draw " + (draw + 1) + ": ");
for (int i = 0; i < 6; i++) {
int num = random.nextInt(49) + 1;
System.out.print(num + " ");
}
System.out.println();
}
}
public static void performRandomSampling(Random random) {
String[] products = {"Laptop", "Phone", "Tablet", "Monitor", "Keyboard", "Mouse"};
String[] customers = {"Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"};
System.out.println("Random product survey sample:");
for (int i = 0; i < 4; i++) {
String product = products[random.nextInt(products.length)];
String customer = customers[random.nextInt(customers.length)];
int rating = random.nextInt(5) + 1; // 1-5 stars
System.out.printf(" %s rated %s: %d/5 stars%n", customer, product, rating);
}
}
public static void generateCharacterStats(Random random) {
System.out.println("Random RPG Character:");
String[] classes = {"Warrior", "Mage", "Rogue", "Archer", "Cleric"};
String characterClass = classes[random.nextInt(classes.length)];
int strength = random.nextInt(10) + 1;
int intelligence = random.nextInt(10) + 1;
int agility = random.nextInt(10) + 1;
int health = random.nextInt(50) + 50;
System.out.println(" Class: " + characterClass);
System.out.println(" Strength: " + strength);
System.out.println(" Intelligence: " + intelligence);
System.out.println(" Agility: " + agility);
System.out.println(" Health: " + health);
}
}
Output:
=== REAL-WORLD APPLICATIONS === === DICE GAME === Player 1 rolled: 4 Player 2 rolled: 2 Player 1 wins! === PASSWORD GENERATOR === Generated passwords: Password 1: aB3#kL9@mN2$ Password 2: xY8!qR4%zW1& Password 3: pQ7$jM5#tV3* === LOTTERY NUMBERS === Lottery numbers (1-49): Draw 1: 15 32 7 44 19 28 Draw 2: 3 41 12 36 25 49 === RANDOM SAMPLING === Random product survey sample: Bob rated Monitor: 4/5 stars Eve rated Phone: 5/5 stars Charlie rated Laptop: 3/5 stars Alice rated Tablet: 4/5 stars === GAME CHARACTER === Random RPG Character: Class: Rogue Strength: 7 Intelligence: 9 Agility: 8 Health: 87
Example 5: Random with Collections and Arrays
import java.util.*;
public class RandomWithCollections {
public static void main(String[] args) {
Random random = new Random();
System.out.println("=== RANDOM WITH COLLECTIONS ===");
// 1. Random element from array
String[] fruits = {"Apple", "Banana", "Orange", "Grape", "Mango"};
System.out.println("Random fruit: " + getRandomElement(random, fruits));
// 2. Random element from List
List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50, 60, 70, 80, 90, 100);
System.out.println("Random number: " + getRandomElement(random, numbers));
// 3. Shuffle list randomly
List<String> cards = new ArrayList<>(Arrays.asList(
"Ace", "King", "Queen", "Jack", "10", "9", "8", "7"
));
System.out.println("Original cards: " + cards);
Collections.shuffle(cards, random);
System.out.println("Shuffled cards: " + cards);
// 4. Random subset from collection
Set<String> colors = new HashSet<>(Arrays.asList(
"Red", "Blue", "Green", "Yellow", "Purple", "Orange", "Pink"
));
Set<String> randomColors = getRandomSubset(random, colors, 3);
System.out.println("Random color subset: " + randomColors);
// 5. Weighted random selection
System.out.println("\n=== WEIGHTED RANDOM SELECTION ===");
Map<String, Double> itemProbabilities = new HashMap<>();
itemProbabilities.put("Common Item", 0.60); // 60% chance
itemProbabilities.put("Rare Item", 0.30); // 30% chance
itemProbabilities.put("Legendary Item", 0.10); // 10% chance
System.out.println("Loot drops:");
for (int i = 0; i < 10; i++) {
String loot = getWeightedRandom(random, itemProbabilities);
System.out.println(" Drop " + (i + 1) + ": " + loot);
}
}
// Get random element from array
public static <T> T getRandomElement(Random random, T[] array) {
int index = random.nextInt(array.length);
return array[index];
}
// Get random element from list
public static <T> T getRandomElement(Random random, List<T> list) {
int index = random.nextInt(list.size());
return list.get(index);
}
// Get random subset from collection
public static <T> Set<T> getRandomSubset(Random random, Collection<T> collection, int size) {
List<T> list = new ArrayList<>(collection);
Collections.shuffle(list, random);
Set<T> result = new HashSet<>();
for (int i = 0; i < Math.min(size, list.size()); i++) {
result.add(list.get(i));
}
return result;
}
// Weighted random selection
public static String getWeightedRandom(Random random, Map<String, Double> probabilities) {
double randomValue = random.nextDouble();
double cumulativeProbability = 0.0;
for (Map.Entry<String, Double> entry : probabilities.entrySet()) {
cumulativeProbability += entry.getValue();
if (randomValue <= cumulativeProbability) {
return entry.getKey();
}
}
// Fallback - return last item
return probabilities.keySet().iterator().next();
}
}
Output:
=== RANDOM WITH COLLECTIONS === Random fruit: Orange Random number: 70 Original cards: [Ace, King, Queen, Jack, 10, 9, 8, 7] Shuffled cards: [7, Queen, 10, 8, King, Ace, 9, Jack] Random color subset: [Red, Pink, Yellow] === WEIGHTED RANDOM SELECTION === Loot drops: Drop 1: Common Item Drop 2: Common Item Drop 3: Rare Item Drop 4: Common Item Drop 5: Common Item Drop 6: Common Item Drop 7: Rare Item Drop 8: Common Item Drop 9: Legendary Item Drop 10: Common Item
Example 6: Gaussian (Normal) Distribution
import java.util.Random;
public class GaussianRandom {
public static void main(String[] args) {
Random random = new Random();
System.out.println("=== GAUSSIAN (NORMAL) DISTRIBUTION ===");
// Gaussian distribution with mean 0.0 and standard deviation 1.0
System.out.println("Standard Gaussian values:");
for (int i = 0; i < 10; i++) {
double gaussian = random.nextGaussian();
System.out.printf(" %.4f%n", gaussian);
}
// Custom Gaussian distribution (mean and standard deviation)
double mean = 100.0; // Average value
double stdDev = 15.0; // Standard deviation
System.out.println("\nIQ Scores (mean=100, stdDev=15):");
int[] iqRanges = new int[7]; // <70, 70-85, 86-100, 101-115, 116-130, 131-145, >145
for (int i = 0; i < 1000; i++) {
double iq = mean + (random.nextGaussian() * stdDev);
if (iq < 70) iqRanges[0]++;
else if (iq < 85) iqRanges[1]++;
else if (iq < 100) iqRanges[2]++;
else if (iq < 115) iqRanges[3]++;
else if (iq < 130) iqRanges[4]++;
else if (iq < 145) iqRanges[5]++;
else iqRanges[6]++;
}
System.out.println("IQ Distribution from 1000 samples:");
System.out.println(" <70: " + iqRanges[0] + " samples");
System.out.println(" 70-85: " + iqRanges[1] + " samples");
System.out.println(" 86-100: " + iqRanges[2] + " samples");
System.out.println(" 101-115:" + iqRanges[3] + " samples");
System.out.println(" 116-130:" + iqRanges[4] + " samples");
System.out.println(" 131-145:" + iqRanges[5] + " samples");
System.out.println(" >145: " + iqRanges[6] + " samples");
// Height simulation (adult males)
System.out.println("\n=== HEIGHT SIMULATION ===");
double heightMean = 175.0; // cm
double heightStdDev = 7.0; // cm
System.out.println("Random male heights (cm):");
for (int i = 0; i < 10; i++) {
double height = heightMean + (random.nextGaussian() * heightStdDev);
System.out.printf(" %.1f cm%n", height);
}
// Product demand forecasting
System.out.println("\n=== PRODUCT DEMAND FORECASTING ===");
int dailyMean = 50;
int dailyStdDev = 10;
System.out.println("Daily product demand forecast:");
for (int day = 1; day <= 10; day++) {
double demand = dailyMean + (random.nextGaussian() * dailyStdDev);
int roundedDemand = (int) Math.round(Math.max(0, demand)); // No negative demand
System.out.println(" Day " + day + ": " + roundedDemand + " units");
}
}
}
Output:
=== GAUSSIAN (NORMAL) DISTRIBUTION === Standard Gaussian values: -0.2345 1.5678 -1.1234 0.8765 -0.5432 0.1234 1.9876 -0.7654 0.4567 -1.3456 IQ Scores (mean=100, stdDev=15): IQ Distribution from 1000 samples: <70: 23 samples 70-85: 131 samples 86-100: 341 samples 101-115: 345 samples 116-130: 132 samples 131-145: 26 samples >145: 2 samples === HEIGHT SIMULATION === Random male heights (cm): 168.3 cm 179.8 cm 172.1 cm 182.5 cm 175.2 cm 169.7 cm 177.9 cm 171.4 cm 166.8 cm 174.6 cm === PRODUCT DEMAND FORECASTING === Daily product demand forecast: Day 1: 45 units Day 2: 52 units Day 3: 38 units Day 4: 57 units Day 5: 49 units Day 6: 63 units Day 7: 47 units Day 8: 55 units Day 9: 42 units Day 10: 58 units
Example 7: ThreadLocalRandom (Java 7+)
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
public class ThreadLocalRandomExample {
public static void main(String[] args) {
System.out.println("=== THREADLOCALRANDOM (BETTER FOR MULTI-THREADING) ===");
// ThreadLocalRandom is better for multi-threaded environments
ThreadLocalRandom tlr = ThreadLocalRandom.current();
System.out.println("Using ThreadLocalRandom:");
// Same methods as Random class
System.out.println("Random int: " + tlr.nextInt());
System.out.println("Random int 0-99: " + tlr.nextInt(100));
System.out.println("Random int 10-20: " + tlr.nextInt(10, 21));
System.out.println("Random double: " + tlr.nextDouble());
System.out.println("Random double 5.0-10.0: " + tlr.nextDouble(5.0, 10.0));
System.out.println("Random boolean: " + tlr.nextBoolean());
// Performance comparison
System.out.println("\n=== PERFORMANCE COMPARISON ===");
int iterations = 1000000;
// Regular Random
long startTime = System.nanoTime();
Random regularRandom = new Random();
for (int i = 0; i < iterations; i++) {
regularRandom.nextInt();
}
long regularTime = System.nanoTime() - startTime;
// ThreadLocalRandom
startTime = System.nanoTime();
ThreadLocalRandom threadRandom = ThreadLocalRandom.current();
for (int i = 0; i < iterations; i++) {
threadRandom.nextInt();
}
long threadTime = System.nanoTime() - startTime;
System.out.println("Regular Random time: " + regularTime + " ns");
System.out.println("ThreadLocalRandom time: " + threadTime + " ns");
System.out.println("ThreadLocalRandom is " +
(regularTime / (double)threadTime) + "x faster");
// Multi-threading example
System.out.println("\n=== MULTI-THREADING EXAMPLE ===");
Runnable task = () -> {
ThreadLocalRandom localRandom = ThreadLocalRandom.current();
String threadName = Thread.currentThread().getName();
System.out.print(threadName + ": ");
for (int i = 0; i < 3; i++) {
System.out.print(localRandom.nextInt(100) + " ");
}
System.out.println();
};
// Create multiple threads
Thread thread1 = new Thread(task, "Thread-1");
Thread thread2 = new Thread(task, "Thread-2");
Thread thread3 = new Thread(task, "Thread-3");
thread1.start();
thread2.start();
thread3.start();
try {
thread1.join();
thread2.join();
thread3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\n=== WHEN TO USE EACH ===");
System.out.println("Use Random for:");
System.out.println(" - Single-threaded applications");
System.out.println(" - When you need seed control");
System.out.println(" - Simple random number generation");
System.out.println("\nUse ThreadLocalRandom for:");
System.out.println(" - Multi-threaded applications");
System.out.println(" - Better performance in concurrent code");
System.out.println(" - When you don't need seed control");
}
}
Output:
=== THREADLOCALRANDOM (BETTER FOR MULTI-THREADING) === Using ThreadLocalRandom: Random int: -123456789 Random int 0-99: 42 Random int 10-20: 15 Random double: 0.123456789 Random double 5.0-10.0: 7.654321 Random boolean: true === PERFORMANCE COMPARISON === Regular Random time: 12500000 ns ThreadLocalRandom time: 8500000 ns ThreadLocalRandom is 1.47x faster === MULTI-THREADING EXAMPLE === Thread-1: 34 78 15 Thread-2: 92 6 41 Thread-3: 27 83 19 === WHEN TO USE EACH === Use Random for: - Single-threaded applications - When you need seed control - Simple random number generation Use ThreadLocalRandom for: - Multi-threaded applications - Better performance in concurrent code - When you don't need seed control
Example 8: Common Pitfalls and Best Practices
import java.util.Random;
public class PitfallsAndBestPractices {
public static void main(String[] args) {
System.out.println("=== COMMON PITFALLS ===");
// 1. Creating new Random objects repeatedly
System.out.println("1. Don't create new Random objects in loops:");
// ❌ Bad - creates new Random object each iteration
System.out.print("Bad approach: ");
for (int i = 0; i < 5; i++) {
Random badRandom = new Random(); // New object each time!
System.out.print(badRandom.nextInt(100) + " ");
}
System.out.println();
// ✅ Good - reuse same Random object
System.out.print("Good approach: ");
Random goodRandom = new Random();
for (int i = 0; i < 5; i++) {
System.out.print(goodRandom.nextInt(100) + " ");
}
System.out.println("\n");
// 2. Integer division in range calculations
System.out.println("2. Watch for integer division:");
Random random = new Random();
// ❌ Wrong - integer division
double wrong = random.nextInt(100) / 100; // Always 0!
System.out.println("Wrong: " + wrong);
// ✅ Correct - cast to double
double correct = random.nextInt(100) / 100.0;
System.out.println("Correct: " + correct);
System.out.println();
// 3. Off-by-one errors in ranges
System.out.println("3. Range boundaries:");
// Random 1-10
int dice = random.nextInt(10) + 1; // ✅ Correct: 1-10
System.out.println("Dice roll (1-10): " + dice);
// ❌ Wrong: random.nextInt(10) gives 0-9, +1 gives 1-10
// But random.nextInt(11) would give 0-10!
System.out.println();
// 4. Gaussian distribution misunderstanding
System.out.println("4. Gaussian distribution notes:");
System.out.println("nextGaussian() returns values from normal distribution");
System.out.println("Mean ~0.0, Standard Deviation ~1.0");
System.out.println("Values can be negative and exceed typical bounds!");
System.out.println("\n=== BEST PRACTICES ===");
// 1. Reuse Random objects
System.out.println("1. Reuse Random objects - don't create new ones repeatedly");
// 2. Use utility methods for common ranges
System.out.println("2. Create utility methods for common ranges:");
System.out.println(" Random age: " + randomAge(random));
System.out.println(" Random percentage: " + randomPercentage(random));
System.out.println(" Random coin flip: " + randomCoinFlip(random));
// 3. Consider ThreadLocalRandom for multi-threading
System.out.println("3. Use ThreadLocalRandom in multi-threaded applications");
// 4. Test with fixed seeds for reproducibility
System.out.println("4. Use fixed seeds for testing and debugging");
// 5. Understand distribution characteristics
System.out.println("5. Know your distribution:");
System.out.println(" - nextInt(): uniform distribution");
System.out.println(" - nextGaussian(): normal distribution");
System.out.println(" - nextBoolean(): 50/50 distribution");
}
// Utility methods
public static int randomAge(Random random) {
return random.nextInt(83) + 18; // 18-100
}
public static int randomPercentage(Random random) {
return random.nextInt(101); // 0-100
}
public static String randomCoinFlip(Random random) {
return random.nextBoolean() ? "Heads" : "Tails";
}
}
Output:
=== COMMON PITFALLS === 1. Don't create new Random objects in loops: Bad approach: 42 42 42 42 42 Good approach: 34 78 15 92 6 2. Watch for integer division: Wrong: 0.0 Correct: 0.42 3. Range boundaries: Dice roll (1-10): 7 4. Gaussian distribution notes: nextGaussian() returns values from normal distribution Mean ~0.0, Standard Deviation ~1.0 Values can be negative and exceed typical bounds! === BEST PRACTICES === 1. Reuse Random objects - don't create new ones repeatedly 2. Create utility methods for common ranges: Random age: 42 Random percentage: 73 Random coin flip: Heads 3. Use ThreadLocalRandom in multi-threaded applications 4. Use fixed seeds for testing and debugging 5. Know your distribution: - nextInt(): uniform distribution - nextGaussian(): normal distribution - nextBoolean(): 50/50 distribution
Random Class Methods Summary
| Method | Description | Range |
|---|---|---|
nextInt() | Random integer | All possible int values |
nextInt(int bound) | Random integer | 0 to bound-1 |
nextLong() | Random long | All possible long values |
nextDouble() | Random double | 0.0 to 1.0 |
nextFloat() | Random float | 0.0 to 1.0 |
nextBoolean() | Random boolean | true or false |
nextGaussian() | Gaussian double | Mean 0.0, StdDev 1.0 |
nextBytes(byte[]) | Fills array with random bytes | -128 to 127 |
When to Use Which Random Generator
| Use Case | Recommended Class |
|---|---|
| Simple single-threaded apps | Random |
| Multi-threaded applications | ThreadLocalRandom |
| Cryptographic security | SecureRandom |
| Testing with reproducible results | Random with fixed seed |
| High-performance concurrent code | ThreadLocalRandom |
Best Practices
- Reuse Random objects - Don't create new ones in loops
- Use ThreadLocalRandom for multi-threaded applications
- Create utility methods for common range requirements
- Use fixed seeds for testing and reproducible results
- Understand distributions - uniform vs normal vs boolean
- Check range boundaries - watch for off-by-one errors
- Consider performance - ThreadLocalRandom is faster in concurrent code
Conclusion
The Random class is your digital randomness generator in Java:
- ✅ Multiple data types: Integers, doubles, booleans, etc.
- ✅ Range control: Generate numbers within specific bounds
- ✅ Seed control: Reproducible sequences for testing
- ✅ Distribution options: Uniform and Gaussian distributions
- ✅ Thread-safe options: ThreadLocalRandom for concurrent code
Key Takeaways:
- Use
Randomfor simple cases in single-threaded applications - Use
ThreadLocalRandomfor multi-threading - it's faster and safer - Reuse Random objects - creating new ones is inefficient
- Understand distributions - choose the right method for your needs
- Use seeds for testing - reproducible randomness helps debugging
Whether you're building games, simulations, tests, or any application that needs randomness, the Random class and its modern counterpart ThreadLocalRandom provide the tools you need to add controlled unpredictability to your Java programs!