Java隨機數的幾種有趣用法
眾所周知,隨機數是任何一種程式語言最基本的特徵之一。而生成隨機數的基本方式也是相同的:產生一個0到1之間的隨機數。看似簡單,但有時我們也會忽略了一些有趣的功能。
我們從書本上學到什麼?
最明顯的,也是直觀的方式,在Java中生成隨機數只要簡單的呼叫:
java.lang.Math.random()
在所有其他語言中,生成隨機數就像是使用Math工具類,如abs, pow, floor, sqrt和其他數學函式。大多數人通過書籍、教程和課程來了解這個類。一個簡單的例子:從0.0到1.0之間可以生成一個雙精度浮點數。那麼通過上面的資訊,開發人員要產生0.0和10.0之間的雙精度浮點數會這樣來寫:
Math.random() * 10
而產生0和10之間的整數,則會寫成:
Math.round(Math.random() * 10)
進 階
通過閱讀Math.random()的原始碼,或者乾脆利用IDE的自動完成功能,開發人員可以很容易發現,java.lang.Math.random()使用一個內部的隨機生成物件 – 一個很強大的物件可以靈活的隨機產生:布林值、所有數字型別,甚至是高斯分佈。例如:
new java.util.Random().nextInt(10)
它有一個缺點,就是它是一個物件。它的方法必須是通過一個例項來呼叫,這意味著必須先呼叫它的建構函式。如果在記憶體充足的情況下,像上面的表示式是可以接受的;但記憶體不足時,就會帶來問題。
一個簡單的解決方案,可以避免每次需要生成一個隨機數時建立一個新例項,那就是使用一個靜態類。猜你可能想到了java.lang.Math,很好,我們就是改良java.lang.Math的初始化。雖然這個工程量低,但你也要做一些簡單的單元測試來確保其不會出錯。
假設程式需要生成一個隨機數來儲存,問題就又來了。比如有時需要操作或保護種子(seed),一個內部數用來儲存狀態和計算下一個隨機數。在這些特殊情況下,共用隨機生成物件是不合適的。
並 發
在Java EE多執行緒應用程式的環境中,隨機生成例項物件仍然可以被儲存在類或其他實現類,作為一個靜態屬性。幸運的是,java.util.Random是執行緒安全的,所以不存在多個執行緒呼叫會破壞種子(seed)的風險。
另一個值得考慮的是多執行緒java.lang.ThreadLocal的例項。偷懶的做法是通過Java本身API實現單一例項,當然你也可以確保每一個執行緒都有自己的一個例項物件。
雖然Java沒有提供一個很好的方法來管理java.util.Random的單一例項。但是,期待已久的Java 7提供了一種新的方式來產生隨機數:
java.util.concurrent.ThreadLocalRandom.current().nextInt(10)
這個新的API綜合了其他兩種方法的優點:單一例項/靜態訪問,就像Math.random()一樣靈活。ThreadLocalRandom也比其他任何處理高併發的方法要更快。
經驗
Chris Marasti-Georg 指出:
Math.round(Math.random() * 10)
使分佈不平衡,例如:0.0 – 0.499999將四捨五入為0,而0.5至1.499999將四捨五入為1。那麼如何使用舊式語法來實現正確的均衡分佈,如下:
Math.floor(Math.random() * 11)
幸運的是,如果我們使用java.util.Random或java.util.concurrent.ThreadLocalRandom就不用擔心上述問題了。
Java實戰專案裡面介紹了一些不正確使用java.util.Random API的危害。這個教訓告訴我們不要使用:
Math.abs(rnd.nextInt())%n
而使用:
rnd.nextInt(n)
相關文章
- 幾種生成隨機數方法隨機
- 【知識積累】隨機數生成的幾種方法隨機
- java定時器的幾種用法Java定時器
- MATLAB中常用的幾種隨機數生成函式Matlab隨機函式
- Java之獲取隨機數的4種方法Java隨機
- Java for迴圈的幾種用法詳解Java
- PHP生成隨機密碼的幾種方法PHP隨機密碼
- Iterator模式的幾種用法模式
- 隨機數種子(random seed)隨機random
- matlab 隨機數種子Matlab隨機
- C語言生成隨機數函式的用法C語言隨機函式
- numpy各種生成隨機數的方法隨機
- GENERATING INTEGER RANDOM NUMBERS(幾種產生隨機數方法的效率分析) (轉)random隨機
- python中星號變數的幾種特殊用法Python變數
- Shell 中 $ 關於指令碼引數的幾種用法指令碼
- 好程式設計師Java教程分享Java中this的幾種用法程式設計師Java
- java隨機數生成原理Java隨機
- Java 隨機數探祕Java隨機
- Java 控制隨機數出現的機率Java隨機
- 模型事件幾種用法模型事件
- Java 控制隨機數出現的概率Java隨機
- 【java】隨機生成6位的數字Java隨機
- java生成指定範圍的隨機數Java隨機
- 例項複習機器學習數學 - 2. 幾種典型離散隨機變數分佈機器學習隨機變數
- Matlab各種隨機數彙總Matlab隨機
- unordered_map隨機底數種子隨機
- 反向代理的有趣用法
- 獲取兩個數之間的隨機數-java隨機Java
- 關於如何產生隨機數的幾種方法彙總!(2018.07.08)隨機
- 讓遊戲更有趣的祕訣:策略與隨機遊戲隨機
- java1-100隨機數Java隨機
- java 無重複取隨機數Java隨機
- Java 的幾種版本Java
- ORACLE產生隨機數的多種方法分享 轉Oracle隨機
- [Vuex系列] - 細說state的幾種用法Vue
- python幾種裝飾器的用法Python
- c++中&符號的幾種用法C++符號
- Android&Java保留小數位數的幾種寫法AndroidJava