1 java.util.Random
簡要總結寫Random()方法的功能:
(1)java.util.Random類中實現的隨機算法是偽隨機,也就是有規則的隨機,所謂有規則的就是在給定種(seed)的區間內隨機生成數字;
(2)相同種子數的Random對象,相同次數生成的隨機數字是完全相同的;
(3)Random類中各方法生成的隨機數字都是均勻分布的,也就是說區間內部的數字生成的幾率均等;
(4) 47是一個產生隨機數的魔法數字,這個問題到現在都沒人能夠解釋,只是經過很多次試驗得到的,包括《Thinking in java》的作者布魯斯.艾克爾也這么提到:由47做種后,產生的隨機數更加體現了隨機性。它沒有什么具體的意義,只要理解隨機數如果有一個種子,哪么出現了比較隨即的隨機數,而當種子是47的時候,隨即率是最大的。
Random rand = new Random(47);
但是下面兩句代碼放在一起就會有點暈了
andom rand = new Random(47); int i = rand.nextInt(100);
生成的隨機數范圍到底是什么,是0-47還是0-100,跟47和100又有什么關系。
下面Random()方法做一些簡單說明吧。
偽隨機數
對於隨機數,大家都知道,計算機不可能產生完全隨機的數字,所謂的隨機數發生器都是通過一定的算法對事先選定的隨機種子做復雜的運算,用產生的結果來近似的模擬完全隨機數,這種隨機數被稱作偽隨機數。偽隨機數是以相同的概率從一組有限的數字中選取的。所選數字並不具有完全的隨機性,但是從實用的角度而言,其隨機程度已足夠了。偽隨機數的選擇是從隨機種子開始的,所以為了保證每次得到的偽隨機數都足夠地“隨機”,隨機種子的選擇就顯得非常重要。如果隨機種子一樣,那么同一個隨機數發生器產生的隨機數也會一樣。
一般地,我們使用同系統時間有關的參數作為隨機種子。
Random對象的生成
Random類包含兩個構造方法,下面依次進行介紹:
(1)public Random()
該構造方法使用一個和當前系統時間對應的相對時間有關的數字作為種子數,然后使用這個種子數構造Random對象。
public Random() { this(++seedUniquifier + System.nanoTime()); } private static volatile long seedUniquifier = 8682522807148012L;
ps :關於
System.nanoTime
1 System有一個靜態的函數nanoTime函數,該函數是返回納秒的。1毫秒=1納秒*1000*1000 如:long time1=System.nanoTime(); 2 System的nanoTime函數式返回納秒,但是該函數只能用於計算時間差,不能用於計算距離現在的時間。因為是納秒太小了。 如:long time1=System.nanoTime(); for(int i=0;i<200;i++){ System.out.print("."); } long time2=System.nanoTime(); System.out.println(time2-time1); 3 記住,System有一個返回納秒的函數:nanoTime函數,該函數只用於計算時間差。 注意:系統中如果需要計算時間差的,那種很小很小的,可以通過System的nanoTime函數來計算時間差。該函數也只能用於計算時間差。
(2)public Random(long seed)
該構造方法可以通過制定一個種子數進行創建。
Random r = new Random(10);
切記,種子數只是隨機算法的起源數字,和生成的隨機數字的區間無關!
隨機種子對結果的影響
(1)隨機種子一定,隨機數范圍一定,則單個對象單次運行的結果一定
選取隨機種子為47,隨機數最大值為20.
下面代碼運行10次的結果總是為18.
Java代碼
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Random rand = new Random(47);
int j = rand.nextInt(20);
System.out.println(j);
}
}
(2)隨機種子一定,隨機數范圍一定,則多個對象單次運行的結果一定
用相同的隨機種子和隨機范圍生成了兩個Random對象,但j和k的值每次都為18
Java代碼
public static void main(String[] args) { for (int i = 0; i < 10; i++) { Random rand1 = new Random(47); Random rand2 = new Random(47); int j = rand1.nextInt(20); int k = rand2.nextInt(20); System.out.println(j); System.out.println(k); } }
(3)隨機種子一定,隨機數范圍一定,但對象連續調用,運行結果不同
在下面的代碼中一次循環內,rand對象被連續調用了3次,分別輸出了18,15,13.
但每次循環的結果都一樣,18,15,13會被順序循環輸出。
也就是說同一個Random對象在隨機種子和隨着范圍一定的情況下,連續調用的次數不同會生成不同的隨機數。
public static void main(String[] args) { for (int i = 0; i < 10; i++) { Random rand = new Random(47); int j = rand.nextInt(20); int k = rand.nextInt(20); int p = rand.nextInt(20); System.out.println(j); System.out.println(k); System.out.println(p); } }
產生特定區間的隨機值
如產生5-26之間的隨機值,為rand.nextInt(26-5+1)+5;
java.lang.Math.Random;
調用這個Math.Random()函數能夠返回帶正號的double值,該值大於等於0.0且小於1.0,即取值范圍是[0.0,1.0)的左閉右開區間,返回值是一個偽隨機選擇的數,在該范圍內(近似)均勻分布。
