Java Random 含參與不含參構造函數的區別
阿新 • • 發佈:2018-01-10
什麽是 cep zed xxx 結果 對比 target pri urn
##Random 通常用來作為隨機數生成器,它有兩個構造方法:
Random random = new Random();
Random random2 = new Random(50);
1.不含參構造方法:
public Random() {
setSeed(System.nanoTime() + seedBase);
++seedBase;
}
2.含參構造方法:
public Random(long seed) {
setSeed(seed);
}
都調用的 setSeed 方法:
public synchronized void setSeed(long seed) { this.seed = (seed ^ multiplier) & ((1L << 48) - 1); haveNextNextGaussian = false; }
###可以看到,不含參構造方法每次都使用當前時間作為種子,而含參構造方法是以一個固定值作為種子
##什麽是種子 seed 呢?
seed 是 Random 生成隨機數時使用的參數:
Random 中最重要的就是 next(int) 方法,使用 seed 進行計算:
protected synchronized int next(int bits) {
seed = (seed * multiplier + 0xbL) & ((1L << 48) - 1);
return (int) (seed >>> (48 - bits));
}
其他 nextXXX 方法都是調用的 next()。
比如 nextInt(int):
public int nextInt(int n) { if (n <= 0) { throw new IllegalArgumentException("n <= 0: " + n); } if ((n & -n) == n) { //調用 next() 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; }
再比如 nextBoolean():
//也是調用的 next()
public boolean nextBoolean() {
return next(1) != 0;
}
##舉個栗子:
@Test
public void testRandomParameter(){
System.out.println("Random 不含參構造方法:");
for (int i = 0; i < 5; i++) {
Random random = new Random();
for (int j = 0; j < 8; j++) {
System.out.print(" " + random.nextInt(100) + ", ");
}
System.out.println("");
}
System.out.println("");
System.out.println("Random 含參構造方法:");
for (int i = 0; i < 5; i++) {
Random random = new Random(50);
for (int j = 0; j < 8; j++) {
System.out.print(" " + random.nextInt(100) + ", ");
}
System.out.println("");
}
}
分別用含參構造方法和不含參構造方法創建 5 個隨機生成器對象,每個隨機生成器再生產 8 個隨機數,對比下結果:
再運行一次:
##總結:
通過上述例子可以發現:
隨機數是種子經過計算生成的。
- 不含參的構造函數每次都使用當前時間作為種子,隨機性更強
- 而含參的構造函數其實是偽隨機,更有可預見性
Java Random 含參與不含參構造函數的區別