java中random的幾個方法的使用Math.random()和random().


random

  java中我們有時候也需要使用使用random來產生隨機數,下面我來簡單的介紹下java中random的使用方法

第一種:Math.random()

public static double random()
返回帶正號的  double 值,該值大於等於  0.0 且小於  1.0。返回值是一個偽隨機選擇的數,在該范圍內(近似)均勻分布。

第一次調用該方法時,它將創建一個新的偽隨機數生成器,與以下表達式完全相同

     new java.util.Random

之后,新的偽隨機數生成器可用於此方法的所有調用,但不能用於其他地方。

此方法是完全同步的,可允許多個線程使用而不出現錯誤。但是,如果許多線程需要以極高的速率生成偽隨機數,那么這可能會減少每個線程對擁有自己偽隨機數生成器的爭用。

 返回:

大於等於 0.0 且小於 1.0 的偽隨機 double 值。

 

public class RandomDemo {
    public static void main(String[] args) {
        //創建一個Math.random()的對象
        double random = Math.random();
        //輸出的值是[0.0-1.0)之間的隨機數
        System.out.println(random);
        /*
         * 輸出的結果
         * 第一次:0.8302600019925631
         * 第二次:0.27576570444589144
         * ...
         * */
    }
}

 

第二種:random()

  Random():創建一個新的隨機數生成器。

   Random(long seed):使用單個 long 種子創建一個新的隨機數生成器。

  Random 有一個特點是:

      相同種子數的Random對象,對應相同次數生成的隨機數字是完全相同的

public class RandomDemo {
    public static void main(String[] args) {
        Random random1 = new Random(20);//這個20代表種子數 創建一個新的隨機數生成器
        Random random2 = new Random(20);
        //用for循環輸出隨機次數
        for (int i = 0; i < 20; i++) {
            //打印20次隨機生成的數字
            System.out.print("random1=" + random1.nextInt(20) + ",");
        }
        System.out.println();
        
        for (int j = 0; j < 20; j++) {
            System.out.print("random2=" + random2.nextInt(20) + ",");
        }
    }
    /*
     * 輸出的結果
     * random1=13,random1=16,random1=1,random1=1,random1=5,random1=15,random1=13,
     * random1=15,random1=13,random1=8,
     * random1=6,random1=2,random1=5,random1=10,
     * random1=8,random1=16,random1=4,random1=8,random1=17,random1=6,
     * random2=13,random2=16,random2=1,random2=1,random2=5,random2=15,random2=13,
     * random2=15,random2=13,random2=8,
     * random2=6,random2=2,random2=5,random2=10,
     * random2=8,random2=16,random2=4,random2=8,random2=17,random2=6,
   * 可以看出來輸出的結果完全相同。
     */
}

 

  無種子數random隨機樹

//沒有提前給定種子數
        Random random3 = new Random();
        for(int x=0;x<20;x++){
            System.out.print("random3="+random3.nextInt(20)+",");
        }
        /*
         * 結果為
         * random3=0,random3=9,random3=17,random3=1,random3=8,random3=3,random3=1,random3=9,
         * random3=18,random3=13,random3=8,random3=14,random3=14,random3=4,random3=6,random3=5,random3=4,random3=15,random3=5,random3=19,
         * 每次輸出的結果都不相同
         * */

下面給大家帶來一些java隨機數的源代碼

1,

nextLong

public long nextLong()
返回下一個偽隨機數,它是取自此隨機數生成器序列的均勻分布的 long 值。 nextLong 的常規協定是,偽隨機地生成並返回一個 long 值。

Random 類按如下方式實現 nextLong 方法:

 public long nextLong() {
       return ((long)next(32) << 32) + next(32);
  }
因為 Random 類使用只以 48 位表示的種子,所以此算法不會返回所有可能的 long 值。

 

返回:
下一個偽隨機數,它是此隨機數生成器序列中均勻分布的 long 值。

2,

nextBoolean

public boolean nextBoolean()
返回下一個偽隨機數,它是取自此隨機數生成器序列的均勻分布的 boolean 值。 nextBoolean 的常規協定是,偽隨機地生成並返回一個 boolean 值。值 truefalse 的生成概率(大致)相同。

Random 類按如下方式實現 nextBoolean 方法:

 public boolean nextBoolean() {
   return next(1) != 0;
 }

 

返回:
下一個偽隨機數,它是此隨機數生成器的序列中均勻分布的 boolean 值。

3,

nextFloat

public float nextFloat()
返回下一個偽隨機數,它是取自此隨機數生成器序列的、在 0.01.0 之間均勻分布的 float 值。

nextFloat 的常規協定是,偽隨機地生成並返回一個從 0.0f(包括)到 1.0f(包括)范圍內均勻選擇(大致)的 float 值。所有可能的 224float 值(其形式為 m x 2-24,其中 m 是一個小於 224 的正整數)的生成概率(大致)相同。

Random 類按如下方式實現 nextFloat 方法:

 public float nextFloat() {
      return next(24) / ((float)(1 << 24));
 }

前面的描述中使用了不確定的詞“大致”,因為 next 方法只是一個大致上獨立選擇位的無偏源。如果它是一個隨機選擇位的最佳來源,那么給出的算法應該從規定范圍完全一致地選擇 float 值。

[在 Java 的早期版本中,結果被錯誤地計算為:

 return next(30) / ((float)(1 << 30));
這可能看似等效(如果不是更好的話),但實際上由於浮點數舍入中的偏差,它會導致輕微的不均勻性:有效數的低位更可能是 0 而不是 1。]

 

返回:
下一個偽隨機數,它是取自此隨機數生成器序列的、在 0.01.0 之間均勻分布的 float

4,

nextDouble

public double nextDouble()
返回下一個偽隨機數,它是取自此隨機數生成器序列的、在 0.01.0 之間均勻分布的 double 值。

nextDouble 的常規協定是,偽隨機地生成並返回一個從 0.0d(包括)到 1.0d(不包括)范圍內均勻選擇(大致)的 double 值。

Random 類按如下方式實現 nextDouble 方法:

 public double nextDouble() {
       return (((long)next(26) << 27) + next(27))
           / (double)(1L << 53);
 }

前面的描述中使用了不確定的詞“大致”,因為 next 方法只是一個大致上獨立選擇位的無偏源。如果它是一個隨機選擇位的最佳源,那么給出的算法應該從規定范圍完全一致地選擇 double 值。

[在 Java 的早期版本中,結果被錯誤地計算為:

 return (((long)next(27) << 27) + next(27))
      / (double)(1L << 54);
這可能看似等效(如果不是更好的話),但實際上由於浮點數舍入中的偏差,它會引入較大的不均勻性:有效數的低位出現 0 的可能性是 1 的三倍!這種不均勻性在實踐中可能沒什么關系,但我們總是力求完美。]

 

返回:
下一個偽隨機數,它是此隨機數生成器序列中 0.01.0 之間均勻分布的 double

5,

nextGaussian

public double nextGaussian()
返回下一個偽隨機數,它是取自此隨機數生成器序列的、呈高斯(“正態”)分布的 double 值,其平均值是 0.0,標准差是 1.0

nextGaussian 的常規協定是,偽隨機地生成並返回一個 double 值,該值從(大致)具有平均值 0.0 和標准差 1.0 的標准正態分布中選擇。

Random 類按以下這種線程安全的方式實現 nextGaussian 方法:

 private double nextNextGaussian;
 private boolean haveNextNextGaussian = false;

 public double nextGaussian() {
   if (haveNextNextGaussian) {
     haveNextNextGaussian = false;
     return nextNextGaussian;
   } else {
     double v1, v2, s;
     do {
       v1 = 2 * nextDouble() - 1;   // between -1.0 and 1.0
       v2 = 2 * nextDouble() - 1;   // between -1.0 and 1.0
       s = v1 * v1 + v2 * v2;
     } while (s >= 1 || s == 0);
     double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
     nextNextGaussian = v2 * multiplier;
     haveNextNextGaussian = true;
     return v1 * multiplier;
   }
 }
這使用了 G. E. P. Box、M. E. Muller 和 G. Marsaglia 的 極坐標法 (polar method),該方法在 Donald E. Knuth 的 The Art of Computer Programming, Volume 3: Seminumerical Algorithms 的第 3.4.1 節,小節 C,算法 P 中進行了描述。注意,它只需調用一次 StrictMath.log 和調用一次 StrictMath.sqrt> 就可以生成兩個獨立的值。

 

返回:
下一個偽隨機數,它是取自此隨機數生成器序列的、呈高斯(“正態”)分布的 double 值,其平均值是 0.0,標准差是 1.0

6,

nextInt

public int nextInt(int n)
返回一個偽隨機數,它是取自此隨機數生成器序列的、在 0(包括)和指定值(不包括)之間均勻分布的 int 值。 nextInt 的常規協定是,偽隨機地生成並返回指定范圍中的一個 int 值。所有可能的 nint 值的生成概率(大致)相同。 Random 類按如下方式實現 nextInt(int n) 方法:
 public int nextInt(int n) {
     if (n<=0)
		throw new IllegalArgumentException("n must be positive");

     if ((n & -n) == n)  // i.e., n is a power of 2
         return (int)((n * (long)next(31)) >> 31);

     int bits, val;
     do {
         bits = next(31);
         val = bits % n;
     } while(bits - val + (n-1) < 0);
     return val;
  }

前面的描述中使用了不確定的詞“大致”,因為 next 方法只是一個大致上獨自選擇位的無偏源。如果它是一個隨機選擇位的最佳源,那么給出的算法應該從規定范圍完全一致地選擇 int 值。

該算法稍微有些復雜。它拒絕那些會導致不均勻分布的值(由於 2^31 無法被 n 整除)。某個值被拒絕的概率取決於 n。最壞的情況是 n=2^30+1,拒絕的概率是 1/2,循環終止前的預計迭代次數是 2。

該算法特別對待 n 是 2 的次冪的情況:它從底層偽隨機數生成器中返回正確的高位數。在不是特殊處理的情況中,將返回正確的 位數。眾所周知,線性同余偽隨機數生成器(比如此類所實現的)在其低位的值序列中周期較短。因此,如果 n 是 2 的次冪(冪值較小),則這種特殊情況將大大增加此方法的后續調用所返回的值序列長度。

 

參數:
n - 要返回的隨機數的范圍。必須為正數。
返回:
下一個偽隨機數,在此隨機數生成器序列中 0(包括)和 n(不包括)之間均勻分布的 int 值。
拋出:
IllegalArgumentException - 如果 n 不是正數

7,

nextInt

public int nextInt()
返回下一個偽隨機數,它是此隨機數生成器的序列中均勻分布的 int 值。 nextInt 的常規協定是,偽隨機地生成並返回一個 int 值。所有 2 32 個可能 int 值的生成概率(大致)相同。

Random 類按如下方式實現 nextInt 方法:

 public int nextInt() {
   return next(32);
 }

 

返回:
下一個偽隨機數,它是此隨機數生成器的序列中均勻分布的 int 值。

8,

nextBytes

public void nextBytes(byte[] bytes)
生成隨機字節並將其置於用戶提供的 byte 數組中。所生成的隨機字節數等於該 byte 數組的長度。

Random 類按如下方式實現 nextBytes 方法:

 public void nextBytes(byte[] bytes) {
   for (int i = 0; i < bytes.length; )
     for (int rnd = nextInt(), n = Math.min(bytes.length - i, 4);
          n-- > 0; rnd >>= 8)
       bytes[i++] = (byte)rnd;
 }

 

參數:
bytes - 用隨機字節填充的 byte 數組
拋出:
NullPointerException - 如果 byte 數組為 null

9,

next

protected int next(int bits)
生成下一個偽隨機數。當被所有其他方法使用時,子類應該重寫此方法。

next 的常規協定是,返回一個 int 值,如果參數 bits 位處於 132(包括)之間,那么返回值的多數低位都將(大致)是單獨選擇的位值,每個位值是 01 的機會(大致)相等。通過將種子自動更新為

(seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)
並返回
(int)(seed >>> (48 - bits))Random 類可實現 next 方法。
這是一個線性同余偽隨機數生成器,由 D. H. Lehmer 定義,Donald E. Knuth 在 The Art of Computer Programming, Volume 3: Seminumerical Algorithms 的第 3.2.1 節中進行了描述。

 

參數:
bits - 隨機位。
返回:
隨機數生成器序列的下一個偽隨機值。

 

 

 

希望有對java隨機數有深入了解的朋友可以給我講解講解!

(個人觀點,錯誤的地方請諒解)

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM