Random 类作为JAVA中用于产生的随机数 ,new  Random(10)  :10是种子数。

注意:Random 的一个特点是:相同种子数的Random对象,对应相同次数生成的随机数字是完全相同的

 

验证代码:

Random r1 = new Random(10);
 
 
 
 
 
        Random r2 = new Random(10);
 
 
 
 
 
        for(int i = 0;i < 4;i++){
 
 
 
 
 
                 System.out.println(r1.nextInt(5));
 
 
        }
 
 
System.out.println("++++++++++++++++++++++");
 
 
        for(int i = 0;i < 4;i++){
 
 
 
 
 
                 System.out.println(r2.nextInt(5));
 
 
        }

结果:r1 产生的随机数

3

0

3

0

++++++++++++++++++++++

3       r2产生的随机数

0

3

0

换成: 

System.out.println(r1.nextDouble(5))System.out.println(r2.nextDouble(5))

结果:

0.7304302967434272

0.2578027905957804

0.059201965811244595

0.24411725056425315

++++++++++++++++++++++

0.7304302967434272

0.2578027905957804

0.059201965811244595

0.24411725056425315

 

分析: 虽然说是随机数发生器,但是还是按照某种算法一步一步执行下去的,种子数一定算法一样那么同一时刻的产生的数值当然该一样了!!

 

* @param seed the initial seed* @see #setSeed(long)*/
++++++++++++++++++带种子数的构造方法+++++++++++++public Random(long seed) {if (getClass() == Random.class)this.seed = new AtomicLong(initialScramble(seed));else {// subclass might have overriden setSeedthis.seed = new AtomicLong();setSeed(seed);}}
 
 
 
++++++++++++++netInt方法带参数的那个源码++++++++++++
 
 
* @since 1.2*/
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 2return (int)((n * (long)next(31)) >> 31);
int bits, val;do {bits = next(31);val = bits % n;} while (bits - val + (n-1) < 0);return val;}
可见Random的种子要求 大于0 的 。。。
 
 
+++++++++++++++nextDouble方法实现+++++++++++
 
 
public double nextDouble() {return (((long)(next(26)) << 27) + next(27))/ (double)(1L << 53);}
+++++++++++++++nextFloat方法实现+++++++++++++
public float nextFloat() {return next(24) / ((float)(1 << 24));}
 
 
 
+++++++++++++++++nextInt方法实现:++++++++++public int nextInt() {return next(32);}

 

可见所有的随机数产生都和一个叫 next方法有关,这个方法是这样的:

* @since 1.1*/protected int next(int bits) {long oldseed, nextseed;AtomicLong seed = this.seed;do {oldseed = seed.get();nextseed = (oldseed * multiplier + addend) & mask;} while (!seed.compareAndSet(oldseed, nextseed));return (int)(nextseed >>> (48 - bits));} 

一般计算机的随机数都是伪随机数,以一个真随机数(种子)作为初始条件,然后用一定的算法不停迭代产生随机数,下面介绍两种方法: 

算法1:平方取中法。
1)将种子设为X0,并mod 10000得到4位数

 

2)将它平方得到一个8位数(不足8位时前面补0)

 

3)取中间的4位数可得到下一个4位随机数X1

 

4)重复1-3步,即可产生多个随机数

 

这个算法的一个主要缺点是最终它会退化成0,不能继续产生随机数。

算法2:线性同余法 

 

1)将种子设为X0,

 

2)用一个算法X(n+1)=(a*X(n)+b) mod c产生X(n+1)

 

一般将c取得很大,可产生0到c-1之间的伪随机数
该算法的一个缺点是会出现循环。

拓展:

Math类中也有一个random方法,该random方法的工作是生成一个[0,1.0)区间的随机小数。

通过阅读Math类的源代码可以发现,Math类中的random方法就是直接调用Random类中的nextDouble方法实现的。

* @see Random#nextDouble()*/public static double random() {Random rnd = randomNumberGenerator;if (rnd == null) rnd = initRNG();return rnd.nextDouble();}