首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 生成指定範圍隨機數的正確姿勢

     編輯:Java 相關知識

Java 中生成指定範圍 [min, max] 的隨機整數,常見錯誤與正確寫法對比,助你避開分佈不均陷阱。

錯誤寫法分析

// 原文提供的寫法(有缺陷)
int s = random.nextInt(max) % (max - min + 1) + min;

問題:nextInt(max) 生成 [0, max-1],而非 [0, max];取模運算導致分佈不均(當 max 非 (max-min+1) 倍數時)。

正確寫法(JDK 1.7+)

// 方法一: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)
  • 加權隨機:前綴和 + 二分查找,或 Alias Method O(1) 取樣
  • 密碼學安全:SecureRandom,效能較低但不可預測

效能與線程安全

常見陷阱總結

  1. nextInt(n) 回傳 [0, n-1],**不包含 n**
  2. 取模 % 會導致分佈偏斜,**嚴禁用於範圍縮放**
  3. ThreadLocalRandom.nextInt(origin, bound) 為**左閉右開** [origin, bound)
  4. 多線程共享 Random 實例有 CAS 競爭,高併發改用 ThreadLocalRandom
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
類別線程安全效能適用場景
Random是(CAS)中一般用途
ThreadLocalRandom線程隔離高高併發、大量生成
SecureRandom是低加密、Token、Session ID