Java 隨機數產生器
通過交互式程式碼範例學習如何在 Java 中產生隨機數。探索 Random.nextInt()、SecureRandom、ThreadLocalRandom 和 Math.random() 的詳細用法。
Java 程式碼編輯器
通過交互式程式碼範例學習如何在 Java 中產生隨機數。探索 Random.nextInt()、SecureRandom、ThreadLocalRandom 和 Math.random() 的詳細用法。
import java.util.Random;
public class RandomExample {
public static void main(String[] args) {
Random rand = new Random();
int min = 1;
int max = 100;
int quantity = 5;
System.out.println("Random numbers between " + min + " and " + max + ":");
for (int i = 0; i < quantity; i++) {
int num = rand.nextInt(max - min + 1) + min;
System.out.print(num + " ");
}
}
}
輸出
這是瀏覽器預覽,不會執行 Java 或 C++;預覽值不適合密碼學用途。
預覽範例
使用 java.util.Random 的基本隨機數
使用 Random.nextInt() 產生指定範圍內的隨機整數。這是 Java 中通用隨機數產生的最常用方法。
需要快速產生隨機數?
試試我們的在線隨機數產生器,無需編寫程式碼即可獲得即時結果。
理解 Java 隨機數產生
Java 提供了多種產生隨機數的方法,每種都針對不同的用例進行了最佳化。java.util.Random 使用線性同余產生器(LCG)演演演演算法,SecureRandom 提供加密強度的隨機數,ThreadLocalRandom 為並發應用提供執行緒安全的產生,Math.random() 提供產生隨機 double 值的簡單方法。
java.util.隨機
java.util.Random 提供快速的偽隨機數產生,適合模擬、遊戲和通用程式設計任務。對於基本使用是執行緒安全的。
SecureRandom
java.security.SecureRandom 使用特定平臺的演演演演算法(SHA1PRNG、NativePRNG)產生加密安全的隨機數,用於安全應用。
ThreadLocalRandom
ThreadLocalRandom 專為多執行緒應用設計,提供高效的執行緒安全隨機數產生,避免競爭和同步開銷。
Math.random()
Math.random() 是一個簡單的方法,返回 0.0 到 1.0 之間的 double 值。適合快速計算,但靈活性不如其他選項。
常見用例
遊戲和模擬
在遊戲循環中使用 Random.nextInt() 或 ThreadLocalRandom 產生隨機骰子擲骰、抽卡、敵人產生和遊戲事件。
安全和加密
使用 SecureRandom 建立安全密碼、API 密鑰、會話令牌和加密鹽,以確保加密強度的隨機性。
並發應用
在並行流和多執行緒應用中使用 ThreadLocalRandom 避免競爭並提高性能。
軟體測試
建立隨機測試資料、模糊測試輸入和邊緣情況,確保 Java 應用的健壯程式碼覆蓋和錯誤檢測。
Java 隨機數產生如何工作
Java 的 java.util.Random 類使用線性同余產生器(LCG)演演演演算法和 48 位種子。它提供了一種產生偽隨機數的簡單方法,並且是執行緒同步的。
SecureRandom 類通過使用特定平臺實現提供加密強度的隨機數。在大多數系統上,它使用作業系統的熵源或硬體隨機數產生器。
ThreadLocalRandom(Java 7 引入)專為多執行緒應用設計。它使用隔離到當前執行緒的隨機數產生器,避免同步開銷和競爭。
實用建議
選擇正確的 API
簡單情況使用 Random,安全相關使用 SecureRandom,並發應用使用 ThreadLocalRandom,快速原型使用 Math.random()。每種都有特定的用例。
安全場景始終使用 SecureRandom
切勿使用 Random 或 Math.random() 產生密碼、令牌或加密操作。始終使用 SecureRandom 確保強隨機性並避免可預測模式。
最佳化並發訪問
在多執行緒應用中,ThreadLocalRandom 比同步 Random 物件快得多。在並行流和並發集合中使用它。
技術規範
演演演演算法
- 線性同余產生器(Random 類)
- SHA1PRNG 或 NativePRNG(SecureRandom)
- ThreadLocalRandom(Java 7+,基於 Random)
- 偽隨機 double(Math.random())
性能特徵
- Math.random():簡單 double 最快
- ThreadLocalRandom:並發訪問最佳
- Random:通用良好,有同步開銷
- SecureRandom:由於熵收集而較慢
常見問題
涵蓋了哪些 Java API?
java.util.Random、SecureRandom、ThreadLocalRandom 和 Math.random(),每個 API 都有一個重點範例。
我可以自訂範例嗎?
是的。在參數面板中設定最小值、最大值和數量,然後運行即可立即查看結果。
為了安全起見,我應該使用哪一個?
SecureRandom。其他 API 是可預測的,不得傳回令牌、金鑰或密碼。
多執行緒程式碼怎麼樣?
ThreadLocalRandom 避免執行緒之間的爭用,是並行流和執行緒池中的常用選擇。
如何在 Java 中產生兩個數值之間的隨機數?
呼叫 nextInt(bound) 可取得從 0 到 bound-1 的數值,因此 nextInt(50) 會產生 0 到 49。若要自訂範圍,可以加上偏移量:nextInt(10) + 5 會產生 5 到 14。從 Java 17 開始,nextInt(origin, bound) 只需一次呼叫即可完成,其中 origin 包含在內,bound 則不包含。
Math.random() 會回傳 1 嗎?
不會。Math.random() 回傳的 double 值範圍從 0.0(包含)到 1.0(不包含),因此可能出現 0.0 或 0.9999,但絕不會是 1.0。它內部其實是委派給單一的 java.util.Random 實例,所以在現代程式碼中直接呼叫 Random 的方法會更清楚。
為什麼每次執行程式都會得到相同的隨機數?
使用固定種子建立的 Random(例如 new Random(42))永遠會產生相同的序列。只要省略種子參數,它就會自動以 System.nanoTime() 結合的唯一值來設定種子。固定種子適合用於需要重現結果的測試和除錯,但不應出現在正式環境的程式碼中。
如何從陣列或清單中隨機挑選一個元素?
產生一個索引並讀取該位置的元素:清單使用 list.get(random.nextInt(list.size())),陣列使用 array[random.nextInt(array.length)],因為 nextInt(n) 的範圍是 0 到 n-1。另一種做法是使用 Collections.shuffle() 一次打亂整個清單的順序,這樣單次洗牌中就不會有元素重複。
參考資料與資源
-
java.util.Random - Official Javadoc
java.util.Random 及其 LCG 內部機制的 Oracle 官方 javadoc。
-
Linear Congruential Generator - Wikipedia
許多執行環境採用的線性同餘產生器演算法。