淺談Java中的幾種隨機數

2021-01-10 CSDN技術社區

眾所周知,隨機數是任何一種程式語言最基本的特徵之一。而生成隨機數的基本方式也是相同的:產生一個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) 

英文出自:summa-tech

譯文出自:oschina

相關焦點

  • Java 生成隨機數的 5 種方式,你知道幾種?
    方法是 的,因此在多線程情況下,只有一個線程會負責創建偽隨機數生成器(使用當前時間作為種子),其他線程則利用該偽隨機數生成器產生隨機數。Java生成隨機數的幾種高級用法,這篇推薦看一下。 因此 方法是線程安全的。
  • Java之Random類的簡單介紹
    第一步,導包:import java.util.Random第二步,創建:Random a=new Random();小括號是可以留空的第三步,使用:如果要獲取一個隨機數int數字(範圍是int所有範圍,有正負兩種):int num=a.nextInt();為了方便大家的理解,小編就先粘幾行代碼,是一個比較簡單的猜數字小遊戲,代碼如下:
  • 打工人打工魂,打工的必會java調用python的幾種用法
    本文轉載自【微信公眾號:五角錢的程式設計師,ID:xianglin965】,經微信公眾號授權轉載,如需轉載與原文作者聯繫圖丨pexelsjava調用python的幾種用法(看這篇就夠了)在java類中直接執行python語句準備工作:創建maven工程,結構如下:到官網https://www.jython.org
  • 詳解Python隨機數的生成
    ,比如密碼加鹽時會在原密碼上關聯一串隨機數,蒙特卡洛算法會通過隨機數採樣等等。Python內置的random模塊提供了生成隨機數的方法,使用這些方法時需要導入random模塊。下面介紹下Python內置的random模塊的幾種生成隨機數的方法。1、random.random()隨機生成 0 到 1 之間的浮點數[0.0, 1.0)。
  • 應用matlab實現幾種常見概率分布隨機數的產生
    隨機數:是專門的隨機試驗的結果。在統計學的不同技術中需要使用隨機數,比如在從統計總體中抽取有代表性的樣本的時候,或者在將實驗動物分配到不同的試驗組的過程中,或者在進行蒙特卡羅模擬法計算的時候等等。1.二項分布隨機數的產生程序如下:clear all;clcr=binornd(10,0.5) %在二項分布中n=10,p=0.5R=binornd(10,0.5,3,4) %產生一個3*4的矩陣運行結果:R =7 5 6 84
  • Java基礎學習:java中的基本數據類型
    2、基本信息 基本類型包括如下幾種:byte、short、int、long、float、double、boolean、char,可以通過相關方法查看範圍大小。
  • 玩轉Python 中的隨機數
    開發中我們經常遇到需要隨機數的場景,比如為了用戶密碼更安全我們有時會加鹽,也就是將用戶原密碼連接上一串隨機字符然後加密保存,又比如我們可能需要隨機展示某張圖片等等。今天,我們就來理一理 Python 中的隨機數的玩法,當然,這裡只涉及標準庫。
  • java float double精度為什麼會丟失?淺談java的浮點數精度問題
    於是帶著這個問 題,做了一次關於float和double學習,做個簡單分享,希望有助於大家對java 浮 點數的理解。 關於 java 的 float 和 doubleJava 語言支持兩種基本的浮點類型: float 和 double 。
  • 如何用java判斷一個數是不是質數?
    哈嘍大家好,這是java小白成長記!昨天分享了怎麼判斷一個數是不是迴文數,目的是為了鞏固一下if選擇語句和求餘數運算符,今天分享一下怎麼判斷一個數是不是質數,可以鞏固for循環、if選擇語句、還有沒怎麼使用過的基本數據類型Boolean。
  • 隨機數
    隨機數,就是隨機生成的數,隨機數最重要的特性是:不可預測。後面的數與前面的數毫無關係,例如:1、200、33、2…..等。
  • Java中Lambda表達式的5種不同語法
    1.標準語法考慮以下示例:String[] arr = {"program", "creek", "is", "a", "java", "site"};Arrays.sort在這種情況下,它是一個單一表達式-Integer.compare(m.length(), n.length())Output:[a, is, java, site, creek, program]2.可以推斷參數類型
  • Excel生成隨機數的技巧,隨機數發生器,你用過嗎
    Excel獲取隨機數從概率分布中產生隨機樣本,其基本原理是隨機數的概念。隨機數是均勻分布在0和1之間的數。從技術上講,電腦不能產生真正的隨機數,因為它們必須使用一個可預測的算法。但是,設計用於產生一個數列的算法,似乎是隨機的。在 Excel中,我們可以使用函數RAND()在任何一個單元格之中產生隨機數。
  • excel隨機數函數是什麼?excel怎樣生成隨機數?
    本篇將介紹excel隨機數函數是什麼?excel怎樣生成隨機數?有興趣的朋友可以了解一下!一、前言excel是我們工作中很常用的一款表格製作工具,它不僅僅只是用來製作表格,它還能對表格中的數據進行處理(比如:運算、排序、篩選等)。excel為數據的處理提供了很多函數,今天小編要介紹的是excel隨機數函數,以及隨機數函數的用法,希望對大家有所幫助!
  • 單片機隨機數:rand(),srand()
    順手些了幾個函數,作為擴展。C不支持可變參數,也不支持overloard,所以只能用不同的函數名稱表示。當然也可以傳入個hash的數據結構作為參數(ruby like)。通常的做法是以這樣一句代碼srand((unsigned) time(NULL));來取代,這樣將使得種子為一個不固定的數, 這樣產生的隨機數就不會每次執行都一樣了。
  • 淺談環保數採儀在工業汙水處理中的應用
    打開APP 淺談環保數採儀在工業汙水處理中的應用 計訊 發表於 2021-01-07 11:57:46 工業汙水處理是我國工業發展方面的一項重點
  • 程式語言中循環結構的實例講解,隨機加法運算器
    在前幾天的文章中通過實例介紹了循環結構中while和do while語句的使用。今天的文章,我們通過一個案例「隨機加法運算器」加深一下for語句的理解和實際應用。問題有加法運算程序。本案例要求使用交互的方式實現此遊戲,交互過程為:-程序開始,即出現一道加法題(兩個加數均為0到99之間的隨機數),並提示用戶輸入該題目的答案(輸入-1則會提前退出程序)。如圖所示-用戶錄入後,程序進行判斷:如果用戶輸入的答案錯誤,則提示「Error!」
  • java第三章循環結構和random知識點總結
    Random5.1 Random產生隨機數(掌握)概述:Random類似Scanner,也是Java提供好的API,內部提供了產生隨機數的功能API後續課程詳細講解,現在可以簡單理解為Java已經寫好的代碼使用步驟:導入包import java.util.Random;創建對象
  • Java8 lambda表達式
    同匿名內部類做法另外一種不同就是,我們申明變量的方式,之前,我們需要顯示申明類型ActionEvent,在該例中,我們不需要提供類型,編譯也能通過,在這背後發生的是javac從上下文獲取event類型,此處是從addActionListener籤名中獲取,這意味著你不需要顯示申明其類型,我們之後會更加詳細討論這種設計,首先讓我們看看編寫lambda表達式幾種不同的方法。
  • Java常見內存溢出異常分析
    at java.util.Arrays.copyof(Arrays.java:3181)   堆內存溢出的時候,虛擬機會拋出java.lang.OutOfMemoryError:java heap space,出現此種情況的時候,我們需要根據內存溢出的時候產生的dump文件來具體分析(需要增加-XX:+HeapDumpOnOutOfMemoryErrorjvm啟動參數)。
  • 聊一聊網際網路基礎設施——隨機數
    網際網路基礎設施我們可以簡單的認為就是提供網絡服務,包括接入網絡、網站託管、CDN加速、域名服務等等,這些都組成了現在的網際網路,網際網路中的數據通過網線、光纖、衛星信號等等進行不斷的交換,那麼這裡安全性就要有一個保障,否則任何人都可以隨意的接收和破解這些信號信息,從而獲得機密信息。如何保證這些傳輸中的信息安全性呢?