• 关于Random的构造函数叙述如下 转


    JDK中关于Random的构造函数叙述如下:

    public Random()
    
    创建一个新的随机数生成器。此构造方法为随机数生成器的种子设置某个值,该值与此构造方法的所有其他调用所用的值完全不同。
    public Random(long seed)
    
    使用单个 long种子创建一个新随机数生成器:
    public Random(long seed) { setSeed(seed); }
    
    next 方法使用它来保存随机数生成器的状态。 
    
    参数:seed - 初始种子。 
    
    另请参见: Random的setSeed(long)
    public void setSeed(long seed)
    
    使用单个 long 种子设置此随机数生成器的种子。setSeed 的常规协定是它更改此随机数生成器对象的状态,使其状态好像是刚刚使用参数 seed 作为种子创建它的状态一样。Random 类按如下方式实现 setSeed方法:
    synchronized public void setSeed(long seed) {
           this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
           haveNextNextGaussian = false;
     }
    
    Random 类实现的 setSeed恰好只使用 48 位的给定种子。但是,通常重写方法可能使用 long 参数的所有 64 位作为种子值。 注:尽管种子值是一个基本的 AtomicLong,但仍必须对此方法同步,确保 haveNextNextGaussian 的语义正确。
    参数:
    seed - 初始种子。
    观察如下的代码
    

    public class Test {
    public static void main(String args[]) throws Throwable {
       for(int i=0;i<10;i++)
            System.out.print((new Random(10)).nextInt(10));
       for(int j=0;j<10;j++)
            System.out.print((new Random()).nextInt(10));
    }
    }

    输出接结果是:33333333333012603015

    当为其指定种子为10时,随机出来的数是相同的,不指定时随机的数是大多不相同的。

    因为在不指定种子的构造函数时系统根据当前时间生成种子,每个种子对应一个数列,相同的种子会得到相同数列,而不是数值。所以如果在构造函数中指定种子,会得到同一个数列。

    实际上Random是一种伪随机数,相同的种子产生相同的序列(注意不是相同数值)。

    Random的nextInt实现如下,依赖于next

    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方法实现如下:

    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));
        }

    next依赖于seed生成一个随机数,如果seed相同则生成同一随机数列

    观看如下代码:

    Random rand = new Random(47);
    Random rand2 = new Random(47);
       int i = rand.nextInt(100);
       int j = rand.nextInt(100);
       int i1 = rand2.nextInt(100);
       int j1 = rand2.nextInt(100);
            System.out.print(i+".");
            System.out.print(j+".");
            System.out.print(i1+".");
            System.out.print(j1+".");

    结果:58.55.58.55.

    说明得到的是同一值序列而非同一个值。

  • 相关阅读:
    BGP--边界网关协议
    Paris Traceroute
    网站flash黑屏问题
    org.pentaho.di.ui.core.widget.PasswordTextVar
    java 金额计算,商业计算 double不精确问题 BigDecimal,Double保留两位小数方法
    spring mvc 利用匿名内部类构建返回json对象
    bootstrap3-typeahead 自动补全
    高德地图 省市区商圈数据
    小米wifi远程提交下载任务地址
    国外HTML网站模版(卖成品模版)
  • 原文地址:https://www.cnblogs.com/carbs/p/2578281.html
Copyright © 2020-2023  润新知