Appearance
16.1 Random 随机数
Random 类的概念
Random 类是 Java 中用于生成伪随机数的类,位于 java.util 包中。它可以生成各种类型的随机数,如整数、浮点数等。
Random 类的使用
创建 Random 对象
java
import java.util.Random;
// 创建 Random 对象
Random random = new Random();
// 使用种子创建 Random 对象(种子相同,生成的随机数序列相同)
Random randomWithSeed = new Random(12345);生成随机数
生成 int 类型的随机数
java
// 生成 0 到 Integer.MAX_VALUE 之间的随机整数
int randomInt = random.nextInt();
// 生成 0 到 n-1 之间的随机整数
int randomIntInRange = random.nextInt(100); // 生成 0-99 之间的随机整数生成 long 类型的随机数
java
// 生成 0 到 Long.MAX_VALUE 之间的随机长整数
long randomLong = random.nextLong();生成 float 类型的随机数
java
// 生成 0.0f 到 1.0f 之间的随机浮点数
float randomFloat = random.nextFloat();生成 double 类型的随机数
java
// 生成 0.0d 到 1.0d 之间的随机双精度浮点数
double randomDouble = random.nextDouble();生成 boolean 类型的随机值
java
// 生成随机布尔值(true 或 false)
boolean randomBoolean = random.nextBoolean();生成字节数组的随机值
java
// 生成指定长度的随机字节数组
byte[] bytes = new byte[10];
random.nextBytes(bytes);示例:Random 类的应用
示例 1:生成指定范围的随机数
java
import java.util.Random;
public class RandomRangeExample {
public static void main(String[] args) {
Random random = new Random();
// 生成 1-100 之间的随机整数
int randomNum = random.nextInt(100) + 1;
System.out.println("1-100 之间的随机数: " + randomNum);
// 生成 50-150 之间的随机整数
int min = 50;
int max = 150;
int rangeRandom = random.nextInt(max - min + 1) + min;
System.out.println("50-150 之间的随机数: " + rangeRandom);
}
}示例 2:生成随机字符串
java
import java.util.Random;
public class RandomStringExample {
public static void main(String[] args) {
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder();
// 生成 10 位随机字符串
for (int i = 0; i < 10; i++) {
int index = random.nextInt(chars.length());
sb.append(chars.charAt(index));
}
System.out.println("随机字符串: " + sb.toString());
}
}示例 3:模拟掷骰子
java
import java.util.Random;
public class DiceRollExample {
public static void main(String[] args) {
Random random = new Random();
// 模拟掷骰子(1-6)
int dice = random.nextInt(6) + 1;
System.out.println("骰子点数: " + dice);
// 模拟掷两个骰子
int dice1 = random.nextInt(6) + 1;
int dice2 = random.nextInt(6) + 1;
System.out.println("第一个骰子: " + dice1 + ", 第二个骰子: " + dice2 + ", 总和: " + (dice1 + dice2));
}
}示例 4:随机选择数组元素
java
import java.util.Random;
public class RandomArrayElementExample {
public static void main(String[] args) {
String[] fruits = {"苹果", "香蕉", "橙子", "梨", "葡萄"};
Random random = new Random();
// 随机选择一个水果
int index = random.nextInt(fruits.length);
System.out.println("随机选择的水果: " + fruits[index]);
}
}ThreadLocalRandom 类
Java 7 引入了 ThreadLocalRandom 类,它是 Random 类的子类,专门为多线程环境设计,提供了更好的性能。
ThreadLocalRandom 的使用
java
import java.util.concurrent.ThreadLocalRandom;
public class ThreadLocalRandomExample {
public static void main(String[] args) {
// 获取 ThreadLocalRandom 实例
ThreadLocalRandom random = ThreadLocalRandom.current();
// 生成随机数
int randomInt = random.nextInt();
int randomIntInRange = random.nextInt(100); // 生成 0-99 之间的随机整数
double randomDouble = random.nextDouble();
boolean randomBoolean = random.nextBoolean();
System.out.println("随机整数: " + randomInt);
System.out.println("0-99 之间的随机整数: " + randomIntInRange);
System.out.println("随机双精度浮点数: " + randomDouble);
System.out.println("随机布尔值: " + randomBoolean);
}
}ThreadLocalRandom 与 Random 的区别
性能:
ThreadLocalRandom在多线程环境下性能更好,因为它为每个线程维护一个独立的随机数生成器线程安全:
ThreadLocalRandom是线程安全的,不需要同步使用方式:
ThreadLocalRandom通过current()方法获取实例,而不是通过构造方法种子:
ThreadLocalRandom自动为每个线程生成种子,不需要手动设置
示例:ThreadLocalRandom 的应用
java
import java.util.concurrent.ThreadLocalRandom;
public class ThreadLocalRandomRangeExample {
public static void main(String[] args) {
ThreadLocalRandom random = ThreadLocalRandom.current();
// 生成 1-100 之间的随机整数
int randomNum = random.nextInt(1, 101); // 注意:ThreadLocalRandom 的 nextInt 方法是 [min, max)
System.out.println("1-100 之间的随机数: " + randomNum);
// 生成 50-150 之间的随机整数
int min = 50;
int max = 151; // 注意:上限是 exclusive
int rangeRandom = random.nextInt(min, max);
System.out.println("50-150 之间的随机数: " + rangeRandom);
}
}常见问题
1. 生成的随机数范围不正确
症状:生成的随机数不在预期范围内
解决方案:正确计算范围,注意 nextInt(n) 生成的是 0 到 n-1 之间的随机数
示例:
java
// 错误:生成的是 0-100 之间的随机数
// int randomNum = random.nextInt(101);
// 正确:生成 1-100 之间的随机数
int randomNum = random.nextInt(100) + 1;2. 种子相同导致随机数相同
症状:使用相同种子创建的 Random 对象生成相同的随机数序列
解决方案:如果需要不同的随机数序列,不要使用相同的种子,或者不指定种子(使用系统时间作为种子)
示例:
java
// 错误:使用相同种子,生成相同的随机数序列
// Random random1 = new Random(12345);
// Random random2 = new Random(12345);
// 正确:不指定种子,使用系统时间作为种子
Random random1 = new Random();
Random random2 = new Random();3. 多线程环境下的性能问题
症状:在多线程环境下,使用 Random 类生成随机数性能较差
解决方案:使用 ThreadLocalRandom 类,它为每个线程维护一个独立的随机数生成器
示例:
java
// 错误:在多线程环境下使用 Random
// Random random = new Random();
// 正确:在多线程环境下使用 ThreadLocalRandom
ThreadLocalRandom random = ThreadLocalRandom.current();最佳实践
选择合适的随机数生成器:
- 单线程环境:使用 Random 类
- 多线程环境:使用 ThreadLocalRandom 类
正确设置随机数范围:
- 注意
nextInt(n)生成的是 0 到 n-1 之间的随机数 - 对于 ThreadLocalRandom,
nextInt(min, max)生成的是 [min, max) 之间的随机数
- 注意
避免使用相同的种子:
- 如果需要不同的随机数序列,不要使用相同的种子
- 不指定种子时,Random 会使用系统时间作为种子
使用随机数的场景:
- 游戏开发:生成随机敌人、随机道具等
- 密码生成:生成随机密码、验证码等
- 模拟测试:生成随机测试数据
- 随机抽样:从数据集中随机选择样本
总结
Random 类是 Java 中用于生成伪随机数的类,它可以生成各种类型的随机数:
基本用法:
- 创建 Random 对象
- 使用各种 nextXxx() 方法生成不同类型的随机数
指定范围:
- 使用
nextInt(n)生成 0 到 n-1 之间的随机整数 - 通过计算生成指定范围的随机数
- 使用
ThreadLocalRandom:
- Java 7 引入的专门为多线程环境设计的随机数生成器
- 性能更好,线程安全
应用场景:
- 游戏开发
- 密码生成
- 模拟测试
- 随机抽样
通过合理使用 Random 类和 ThreadLocalRandom 类,可以满足各种随机数生成的需求。
