软件编程
位置:首页>> 软件编程>> java编程>> 实例讲解Java中random.nextInt()与Math.random()的基础用法

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

作者:wlmmmm  发布时间:2023-11-29 12:29:54 

标签: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));
  }
}

结果为:

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

如不想生成相同的随机数序列,则应只使用一个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://blog.csdn.net/u012099869/article/details/50394644

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com