random.nextInt()与Math.random()基础用法

random.nextInt()与Math.random()基础用法1、来源java.util.Random类中的方法;Math类中的静态方法2、用法产生0-n的伪随机数(伪随机数参看最后注解)://两种生成对象方式:带种子和不带种子(两种方式的区别见注解)Randomrandom=newRandom();Integerres=random.nextInt(n);Integerres=(int)(Math.random()*n);3、

大家好,又见面了,我是你们的朋友全栈君。

1、来源

random.nextInt() 为 java.util.Random类中的方法;
Math.random() 为 java.lang.Math 类中的静态方法。

2、用法

产生0-n的伪随机数(伪随机数参看最后注解):

// 两种生成对象方式:带种子和不带种子(两种方式的区别见注解)
Random random = new Random();
Integer res = random.nextInt(n);
Integer res = (int)(Math.random() * n);

3、jdk源码

// random.nextInt(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;
}
// Math.random()
public static double random() {
   Random rnd = randomNumberGenerator;
   // 第一次调用,生成一个随机数生成器
    if (rnd == null) rnd = initRNG();
    return rnd.nextDouble();
}

// 生成的方法为同步的,线程安全
private static synchronized Random initRNG() {
  Random rnd = randomNumberGenerator;
     return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd;
 }

// 该方法为 Random 类中的方法
public double nextDouble() {
   return (((long)(next(26)) << 27) + next(27))
        / (double)(1L << 53);
}

4、总结

  1. Math.random() 方法生成[0, 1)范围内的double类型随机数;Random类中的nextXxxx系列方法生成0-n的随机数;
  2. Math.random() 线程安全,多线程环境能被调用;
  3. 如无特殊需求,则使用(int)(Math.random()*n)的方式生成随机数即可。

5、注:何谓伪随机数

伪随机既有规则的随机,Random类中的随机算法就是伪随机。
具体表现为:相同种子数的Random对象生成的随机数序列相同:

@Test
public void createProjectNo() {
     Random r1 = new Random(100);
     Random r2 = new Random(100);

     for (int i = 0; i < 100; i ++) {
         System.out.println(r1.nextInt(10)+", "+r2.nextInt(10));
     }
 }

结果为:
随机数生成结果

如不想生成相同的随机数序列,则应只使用一个Random类。而Math类中的随机数生成器 randomNumberGenerator 对象为静态的,可考虑使用。

6、注:Random类的两种构造方法区别

1、 源码

public Random() {
  this(seedUniquifier() ^ System.nanoTime());
}

public Random(long seed) {
    if (getClass() == Random.class)
        this.seed = new AtomicLong(initialScramble(seed));
    else {
        // subclass might have overriden setSeed
        this.seed = new AtomicLong();
        setSeed(seed);
    }
}

2、区别
从源码中可以看到,未定义种子的构造方法里,使用当前系统时间相关的一个数字作为种子数,该种子数只作为随机算法的起源数字,与生成的随机数区间无关系。

这篇文章是我对Java中随机数的一些简单的理解,如有不对的地方或者其他的见解欢迎指导。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/162931.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pytest+allure实战

    pytest+allure实战pytest+allure实战pytest+allure实战基本架构Login.pytest.pyrun_all_case.py测试报告pytest+allure实战写之前,说一下自己的感受,大家之前调试出来的框架什么的一定要做好记录,或者归纳整理好,pytest+allure很久之前就用过了,但是当时出报告以后就扔一边了,当我想整理写一篇关于这个的时候完全找不到在哪,但是脑子里还记的这个框架之前100%用过,就是不知道放哪里了,重新调试也不想调,就一直翻电脑,越翻越燥,大半天也没找见,其实就在我眼皮底

    2022年7月26日
    7
  • 什么是POJO类?

    什么是POJO类?POJO 简单的Java对象(PlainOldJavaObjects)实际就是普通JavaBeans,使用POJO名称是为了避免和EJB混淆起来,而且简称比较直接.其中有一些属性及其gettersetter方法的类,有时可以作为valueobject或dto(DataTransformObject)来使用.当然,如果你有一个简单的运算属性也是可以的,但不允许有业务方法,也

    2022年5月28日
    67
  • oracle查询时使用case,Oracle查询语句中Casewhen的使用[通俗易懂]

    oracle查询时使用case,Oracle查询语句中Casewhen的使用[通俗易懂]casewhen和decode函数用法有一些相似,只是decode是枚举函数,而casewhen则更加灵活,同时casewhen相当于一个特殊的只有两个枚casewhen语句语法如下:casewhen表达式thenvalueAelsevalueBend;具体使用如下:select(casewhena.column1>=1then’成功’e…

    2025年9月17日
    4
  • 邮箱正则表达式

    邮箱正则表达式正则提取国内外所有的邮箱经过测试准确率100%python代码块res=re.search(r’\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,8}\b’,description)ifres:emailAddress=res.group()else:emailAddr…

    2022年6月15日
    30
  • c# 第14节 字符方法、转义字符、字符串的方法[通俗易懂]

    c# 第14节 字符方法、转义字符、字符串的方法

    2022年3月13日
    43
  • eclipse中文版自动补全设置

    eclipse中文版自动补全设置eclipse中文版自动补全设置如下:

    2022年6月28日
    25

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号