Java 提供兩種主要方式產生偽隨機數,適用於不同場景。
import java.util.Random;
public class RandomDemo {
public static void main(String[] args) {
Random random = new Random(); // 預設種子:System.nanoTime()
// 1. 產生 [0, 10) 整數 (含 0,不含 10)
for (int i = 0; i < 20; i++) {
System.out.println(random.nextInt(10));
}
// 2. 其他常用方法
random.nextInt(); // 全 int 範圍
random.nextLong(); // long 範圍
random.nextDouble(); // [0.0, 1.0) double
random.nextFloat(); // [0.0, 1.0) float
random.nextBoolean(); // true/false
random.nextGaussian(); // 高斯分佈 (均值 0, 標準差 1)
random.nextBytes(bytes); // 填充 byte 陣列
}
}
回傳 double,範圍 [0.0, 1.0)。需自行縮放轉型。
public class MathRandomDemo {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
double d = Math.random(); // 0.0 ~ 1.0
d *= 10; // 0.0 ~ 10.0
int n = (int) d; // 0 ~ 9 (截斷向下取整)
System.out.println(n);
}
}
}
// 產生 [min, max] 區間整數 (含 min、含 max)
public static int randomInt(int min, int max) {
return new Random().nextInt(max - min + 1) + min;
}
// 使用 Math.random()
public static int randomIntMath(int min, int max) {
return (int) (Math.random() * (max - min + 1)) + min;
}
加密級強隨機,適用於 Token、Session ID、密碼鹽值。
import java.security.SecureRandom;
public class SecureRandomDemo {
public static void main(String[] args) {
SecureRandom sr = new SecureRandom();
byte[] token = new byte[16];
sr.nextBytes(token);
// 轉十六進位字串
String hex = bytesToHex(token);
System.out.println("安全 Token: " + hex); // 32 字元十六進位
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) sb.append(String.format("%02x", b));
return sb.toString();
}
}
import java.util.concurrent.ThreadLocalRandom;
// 區間整數
int n = ThreadLocalRandom.current().nextInt(1, 101); // [1, 100]
// 區間 double
double d = ThreadLocalRandom.current().nextDouble(0, 1.0);
| 場景 | 推薦類別 | 理由 |
|---|---|---|
| 一般模擬/測試/遊戲 | Random / ThreadLocalRandom | 效能好、API 豐富 |
| 一次性簡單隨機 | Math.random() | 無需建立物件 |
| 多執行緒高併發 | ThreadLocalRandom | 無競爭、效能最佳 |
| 安全 Token/密碼學 | SecureRandom | 不可預測、符合 FIPS |
| 可重現測試 (固定種子) | new Random(seed) | 結果可預期驗證 |
Math.random() 回傳 double,乘 10 後 (int) 會**截斷小數**而非四捨五入,分佈均勻於 [0, 9]。Random 非執行緒安全,多執行緒共用實例會降低效能,請用 ThreadLocalRandom。System.currentTimeMillis() 當種子做安全用途,極易暴力破解。