Java 中生成指定範圍 [min, max] 的隨機整數,常見錯誤與正確寫法對比,助你避開分佈不均陷阱。
// 原文提供的寫法(有缺陷)
int s = random.nextInt(max) % (max - min + 1) + min;
問題:nextInt(max) 生成 [0, max-1],而非 [0, max];取模運算導致分佈不均(當 max 非 (max-min+1) 倍數時)。
// 方法一:nextInt(bound) 範圍偏移(推薦)
int randomNum = random.nextInt(max - min + 1) + min;
// 生成 [0, max-min] 再偏移 min → [min, max]
// 方法二:ThreadLocalRandom(高併發效能更好)
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);
// 注意:nextInt(origin, bound) 為 [origin, bound) 左閉右開
// 方法三:Random.ints() 串流(JDK 8+)
IntStream stream = random.ints(count, min, max + 1); // 批量生成
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
public class RandomTest {
public static void main(String[] args) {
int min = 10, max = 20;
Random random = new Random();
// 方法一
int n1 = random.nextInt(max - min + 1) + min;
System.out.println("Random.nextInt: " + n1);
// 方法二
int n2 = ThreadLocalRandom.current().nextInt(min, max + 1);
System.out.println("ThreadLocalRandom: " + n2);
// 批量生成 5 個
random.ints(5, min, max + 1).forEach(System.out::println);
}
}
nextLong() 同理,或 ThreadLocalRandom.current().nextLong(min, max + 1)nextDouble() * (max - min) + min 生成 [min, max),或 ThreadLocalRandom.current().nextDouble(min, max)SecureRandom,效能較低但不可預測| 類別 | 線程安全 | 效能 | 適用場景 |
|---|---|---|---|
| Random | 是(CAS) | 中 | 一般用途 |
| ThreadLocalRandom | 線程隔離 | 高 | 高併發、大量生成 |
| SecureRandom | 是 | 低 | 加密、Token、Session ID |