核心原理:偽隨機與種子
java.util.Random 採用線性同餘法(LCG)實現偽隨機。相同種子的 Random 實例,調用次數相同時產出的序列完全一致。這在測試復現、加密協商中極其重要。
// 系統時間種子 (最常用)
Random r1 = new Random();
// 固定種子 (可復現)
Random r2 = new Random(12345L);
// 重置種子
r1.setSeed(67890L);
核心 API 速查表
| 方法 | 返回範圍 | 分布 | 典型用途 |
| nextBoolean() | true/false | 均勻 50% | 隨機決策、A/B 測試分流 |
| nextDouble() | [0.0, 1.0) | 均勻 | 機率計算、蒙特卡洛模擬 |
| nextInt() | [-2^31, 2^31-1] | 均勻 | 全域隨機標識、雜湊鹽值 |
| nextInt(n) | [0, n) | 均勻 | 索引隨機、負載均衡選節點 |
| nextLong() | Long 全域 | 均勻 | 分散式 ID 生成片段 |
| nextGaussian() | 常態分布 μ=0,σ=1 | 高斯 | 擬真數據生成、干擾注入 |
任意區間隨機數生成公式
整數區間 [min, max] (含邊界)
// 公式:min + nextInt(max - min + 1)
int randomInt = min + r.nextInt(max - min + 1);
// 範例:擲骰子 [1,6]
int dice = 1 + r.nextInt(6);
浮點數區間 [min, max)
// 公式:min + nextDouble() * (max - min)
double randomDouble = min + r.nextDouble() * (max - min);
// 範例:價格波動 [9.9, 19.9)
double price = 9.9 + r.nextDouble() * 10.0;
概率控制實戰:加權隨機
需求:物品掉落機率——稀有 5%、精良 20%、普通 75%
int roll = r.nextInt(100); // [0, 99]
String item;
if (roll < 5) item = "稀有";
else if (roll < 25) item = "精良";
else item = "普通";
// 通用加權工具
public static <T> T weightedRandom(Map<T, Integer> weightMap, Random r) {
int total = weightMap.values().stream().mapToInt(Integer::intValue).sum();
int roll = r.nextInt(total);
int acc = 0;
for (Map.Entry<T, Integer> e : weightMap.entrySet()) {
acc += e.getValue();
if (roll < acc) return e.getKey();
}
throw new IllegalStateException("算法邏輯錯誤");
}
避坑指南
- 多執行緒共享 Random:
Random 為執行緒安全但有鎖競爭,高併發用 ThreadLocalRandom (JDK 7+)
- 安全敏感場景:必須用
SecureRandom (種子來自 OS 熵池)
- 避免頻繁 new Random():短時間內系統時間種子可能相同,導致序列重複
Math.random() 本質調用 Random.nextDouble(),僅語法糖
進階:SplittableRandom (JDK 8+)
支援 split() 派生子生成器,適合 Fork/Join 平行流水線,無鎖、統計品質優於 Random。
- 上一篇文章: SpringMVC + MyBatis 企業級框架整合實戰:從代碼生成到分佈式緩存的全棧落地
- 下一篇文章: Jetty 載入 Spring 容器源碼深度解析:Listener 與 Servlet 初始化順序的底層邏輯
Copyright ©
程式碼之家 All Rights Reserved