Random Class for Number Generation in Java

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:

  1. Random() - Uses current time as seed
  2. Random(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

MethodDescriptionRange
nextInt()Random integerAll possible int values
nextInt(int bound)Random integer0 to bound-1
nextLong()Random longAll possible long values
nextDouble()Random double0.0 to 1.0
nextFloat()Random float0.0 to 1.0
nextBoolean()Random booleantrue or false
nextGaussian()Gaussian doubleMean 0.0, StdDev 1.0
nextBytes(byte[])Fills array with random bytes-128 to 127

When to Use Which Random Generator

Use CaseRecommended Class
Simple single-threaded appsRandom
Multi-threaded applicationsThreadLocalRandom
Cryptographic securitySecureRandom
Testing with reproducible resultsRandom with fixed seed
High-performance concurrent codeThreadLocalRandom

Best Practices

  1. Reuse Random objects - Don't create new ones in loops
  2. Use ThreadLocalRandom for multi-threaded applications
  3. Create utility methods for common range requirements
  4. Use fixed seeds for testing and reproducible results
  5. Understand distributions - uniform vs normal vs boolean
  6. Check range boundaries - watch for off-by-one errors
  7. 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 Random for simple cases in single-threaded applications
  • Use ThreadLocalRandom for 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!

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper