淺談Java中的n種隨機(jī)數(shù)產(chǎn)生辦法
我們從書本上學(xué)到什么?
最明顯的,也是直觀的方式,在Java中生成隨機(jī)數(shù)只要簡單的調(diào)用:
java.lang.Math.random()
在所有其他語言中,生成隨機(jī)數(shù)就像是使用Math工具類,如abs, pow, floor, sqrt和其他數(shù)學(xué)函數(shù)。大多數(shù)人通過書籍、教程和課程來了解這個類。一個簡單的例子:從0.0到1.0之間可以生成一個雙精度浮點(diǎn)數(shù)。那么通過上面的信息,開發(fā)人員要產(chǎn)生0.0和10.0之間的雙精度浮點(diǎn)數(shù)會這樣來寫:
Math.random() * 10
而產(chǎn)生0和10之間的整數(shù),則會寫成:
Math.round(Math.random() * 10)
進(jìn) 階
通過閱讀Math.random()的源碼,或者干脆利用IDE的自動完成功能,開發(fā)人員可以很容易發(fā)現(xiàn),java.lang.Math.random()使用一個內(nèi)部的隨機(jī)生成對象 - 一個很強(qiáng)大的對象可以靈活的隨機(jī)產(chǎn)生:布爾值、所有數(shù)字類型,甚至是高斯分布。例如:
new java.util.Random().nextInt(10)
它有一個缺點(diǎn),就是它是一個對象。它的方法必須是通過一個實(shí)例來調(diào)用,這意味著必須先調(diào)用它的構(gòu)造函數(shù)。如果在內(nèi)存充足的情況下,像上面的表達(dá)式是可以接受的;但內(nèi)存不足時,就會帶來問題。
一個簡單的解決方案,可以避免每次需要生成一個隨機(jī)數(shù)時創(chuàng)建一個新實(shí)例,那就是使用一個靜態(tài)類。猜你可能想到了java.lang.Math,很好,我們就是改良java.lang.Math的初始化。雖然這個工程量低,但你也要做一些簡單的單元測試來確保其不會出錯。
假設(shè)程序需要生成一個隨機(jī)數(shù)來存儲,問題就又來了。比如有時需要操作或保護(hù)種子(seed),一個內(nèi)部數(shù)用來存儲狀態(tài)和計(jì)算下一個隨機(jī)數(shù)。在這些特殊情況下,共用隨機(jī)生成對象是不合適的。
并 發(fā)
在Java EE多線程應(yīng)用程序的環(huán)境中,隨機(jī)生成實(shí)例對象仍然可以被存儲在類或其他實(shí)現(xiàn)類,作為一個靜態(tài)屬性。幸運(yùn)的是,java.util.Random是線程安全的,所以不存在多個線程調(diào)用會破壞種子(seed)的風(fēng)險。
另一個值得考慮的是多線程java.lang.ThreadLocal的實(shí)例。偷懶的做法是通過Java本身API實(shí)現(xiàn)單一實(shí)例,當(dāng)然你也可以確保每一個線程都有自己的一個實(shí)例對象。
雖然Java沒有提供一個很好的方法來管理java.util.Random的單一實(shí)例。但是,期待已久的Java 7提供了一種新的方式來產(chǎn)生隨機(jī)數(shù):
java.util.concurrent.ThreadLocalRandom.current().nextInt(10)
這個新的API綜合了其他兩種方法的優(yōu)點(diǎn):單一實(shí)例/靜態(tài)訪問,就像Math.random()一樣靈活。ThreadLocalRandom也比其他任何處理高并發(fā)的方法要更快。
經(jīng)驗(yàn)
Chris Marasti-Georg 指出:
Math.round(Math.random() * 10)
使分布不平衡,例如:0.0 - 0.499999將四舍五入為0,而0.5至1.499999將四舍五入為1。那么如何使用舊式語法來實(shí)現(xiàn)正確的均衡分布,如下:
Math.floor(Math.random() * 11)
幸運(yùn)的是,如果我們使用java.util.Random或java.util.concurrent.ThreadLocalRandom就不用擔(dān)心上述問題了。
Java實(shí)戰(zhàn)項(xiàng)目里面介紹了一些不正確使用java.util.Random API的危害。這個教訓(xùn)告訴我們不要使用:
Math.abs(rnd.nextInt())%n
而使用:
rnd.nextInt(n)
y以上就是關(guān)于Java中的n種隨機(jī)數(shù)的相關(guān)介紹,希望對大家的學(xué)習(xí)有所幫助。
- Java生產(chǎn)1-100的隨機(jī)數(shù)簡單實(shí)例(分享)
- Java編程實(shí)現(xiàn)從給定范圍內(nèi)隨機(jī)N個不重復(fù)數(shù)生成隨機(jī)數(shù)的方法小結(jié)
- Java生成10個1000以內(nèi)的隨機(jī)數(shù)并用消息框顯示數(shù)組內(nèi)容然后求和輸出
- 淺談Java中隨機(jī)數(shù)的幾種實(shí)現(xiàn)方式
- java生成隨機(jī)數(shù)的方法
- 史上最全的java隨機(jī)數(shù)生成算法分享
- 如何用java生成指定范圍的隨機(jī)數(shù)
- java生成指定范圍隨機(jī)數(shù)的多種代碼
相關(guān)文章
Java設(shè)計(jì)模式模板方法模式(Template)用法解析
這篇文章主要介紹了Java設(shè)計(jì)模式模板方法模式(Template)用法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11Java 實(shí)現(xiàn)簡易教務(wù)管理系統(tǒng)的代碼
這篇文章主要介紹了Java 實(shí)現(xiàn)簡易教務(wù)管理系統(tǒng)的代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07JavaWeb 實(shí)現(xiàn)多個文件壓縮下載功能
文件下載時,我們可能需要一次下載多個文件,批量下載文件時,需要將多個文件打包為zip,然后再下載。本文給大家分享實(shí)現(xiàn)思路及具體實(shí)現(xiàn)代碼,對javaweb實(shí)現(xiàn)文件壓縮下載功能感興趣的朋友一起學(xué)習(xí)吧2017-07-07mybatis-generator-gui 工具使用(圖形化工具)
基于 mybatis generator 開發(fā)一款界面工具, 本工具可以使你非常容易及快速生成 Mybatis 的 Java POJO 文件及數(shù)據(jù)庫 Mapping 文件。本文重點(diǎn)給大家介紹mybatis-generator-gui 工具使用,感興趣的朋友一起看看吧2022-03-03SpringBoot + validation 接口參數(shù)校驗(yàn)的思路詳解
這篇文章主要介紹了SpringBoot + validation 接口參數(shù)校驗(yàn),本文通過項(xiàng)目實(shí)踐+場景分析給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10SpringBoot集成WebSocket的兩種方式(JDK內(nèi)置版和Spring封裝版)
這篇文章主要介紹了SpringBoot集成WebSocket的兩種方式,這兩種方式為JDK內(nèi)置版和Spring封裝版,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06SpringBoot報(bào)錯Invalid?bound?statement?(not?found)問題排查和解決方案
這篇文章主要介紹了SpringBoot報(bào)錯Invalid?bound?statement?(not?found)問題排查和解決方案,文中通過圖文結(jié)合的方式講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-03-03Java Spring-Cache key配置注意事項(xiàng)介紹
本文主要對java spring-cache key配置注意事項(xiàng)進(jìn)行了介紹,小編覺得還是挺不錯的,這里分享給大家,供需要的朋友參考。2017-10-10