实例讲解Java中random.nextInt()与Math.random()的基础用法

 更新时间:2019年02月12日 16:35:44   作者:wlmmmm  
今天小编就为大家分享一篇关于实例讲解Java中random.nextInt()与Math.random()的基础用法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

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、小结

  • Math.random() 方法生成[0, 1)范围内的double类型随机数;Random类中的nextXxxx系列方法生成0-n的随机数;
  • Math.random() 线程安全,多线程环境能被调用;
  • 如无特殊需求,则使用(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中随机数的一些简单的理解,如有不对的地方或者其他的见解欢迎指导。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

相关文章

  • Java实现获取内网的所有IP地址

    Java实现获取内网的所有IP地址

    这篇文章主要介绍了如何利用Java语言实现获取内网的所有IP地址,文中的示例代码讲解详细,对我们学习有一定的参考价值,快跟随小编一起学习一下吧
    2022-06-06
  • Java Api实现Elasticsearch的滚动查询功能

    Java Api实现Elasticsearch的滚动查询功能

    这篇文章主要介绍了Java Api实现Elasticsearch的滚动查询,解决ES每次只能查询一万条数据的问题,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-08-08
  • Springboot事件监听与@Async注解详解

    Springboot事件监听与@Async注解详解

    这篇文章主要介绍了Springboot事件监听与@Async注解详解,在开发中经常可以利用Spring事件监听来实现观察者模式,进行一些非事务性的操作,如记录日志之类的,需要的朋友可以参考下
    2024-01-01
  • Java同步锁Synchronized底层源码和原理剖析(推荐)

    Java同步锁Synchronized底层源码和原理剖析(推荐)

    这篇文章主要介绍了Java同步锁Synchronized底层源码和原理剖析,释放后,进入减减操作、直到为0然后唤醒队列,让他们去争夺锁,循环前面步骤,对Java同步锁Synchronized相关知识感兴趣的朋友一起看看吧
    2022-05-05
  • 使用Autowired为什么会被IDEA警告最佳修改方法

    使用Autowired为什么会被IDEA警告最佳修改方法

    这篇文章主要介绍了使用Autowired为什么会被IDEA警告,应该怎么修改最佳,除了使用@Autowired以外,我们其实也有几种好用的方式,使用@Resource替代@Autiwired方法是其中一种,只需要改变一个注解,这里就不展示了,需要的朋友可以参考下
    2023-02-02
  • Java中子类调用父类构造方法的问题分析

    Java中子类调用父类构造方法的问题分析

    本篇文章介绍了,Java中子类调用父类构造方法的问题分析。需要的朋友参考下
    2013-04-04
  • 浅谈如何在项目中使用Spring Cloud Alibaba Sentinel组件

    浅谈如何在项目中使用Spring Cloud Alibaba Sentinel组件

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。本文主要介绍了使用Spring Cloud Alibaba Sentinel组件,感兴趣的可以了解一下
    2021-07-07
  • Java关于MyBatis缓存详解

    Java关于MyBatis缓存详解

    缓存的重要性是不言而喻的,使用缓存,我们可以避免频繁的与数据库进行交互,尤其是在查询越多、缓存命中率越高的情况下,使用缓存对性能的提高更明显。本文将给大家详细的介绍,对大家的学习或工作具有一定的参考借鉴价值
    2021-09-09
  • Spring避免循环依赖的策略详解

    Spring避免循环依赖的策略详解

    在Spring框架中,循环依赖是指两个或多个bean相互依赖对方,形成一个闭环,这在应用启动时可能导致BeanCurrentlyInCreationException异常,本文给大家介绍了Spring中如何避免循环依赖,需要的朋友可以参考下
    2024-02-02
  • Java中的多线程一定就快吗?

    Java中的多线程一定就快吗?

    这篇文章主要介绍了Java 多线程的相关资料,帮助大家是否选择开启多线程,感兴趣的朋友可以了解下
    2020-09-09

最新评论