java 随机数获取

1. Math.random()

产生的随机数是 [0,1) 之间的一个 double,即 0 <= random < 1。

实现原理:

当第一次调用 Math.random() 方法时,自动创建了一个伪随机数生成器,实际上用的是 new java.util.Random()。当接下来继续调用 Math.random() 方法时,就会使用这个新的伪随机数生成器。

 public static double random() {
        return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
    }
 private static final class RandomNumberGeneratorHolder {
    static final Random randomNumberGenerator = new Random();
}

在多线程情况下,只有一个线程会负责创建伪随机数生成器(使用当前时间作为种子),其他线程则利用该伪随机数生成器产生随机数。因此 Math.random() 方法是线程安全的。

2. java.util.Random 工具类

在java.util这个包里面提供了一个Random的类,我们可以新建一个Random的对象来产生随机数,他可以产生随机整数、随机float、随机double,随机long,这个也是我们在j2me的程序里经常用的一个取随机数的方法。

基本算法
linear congruential pseudorandom number generator (LGC) 线性同余法伪随机数生成器

缺点
可预测。从输出中可以很容易计算出种子值。因此可以预测出下一个输出的随机数。
在注重信息安全的应用中,不要使用 LCG 算法生成随机数,请使用 SecureRandom。

Random类提供的方法:API

  • nextBoolean() - 返回均匀分布的 true 或者 false
  • nextBytes(byte[] bytes)
  • nextDouble() - 返回 0.0 到 1.0 之间的均匀分布的 double
  • nextFloat() - 返回 0.0 到1.0 之间的均匀分布的 float
  • nextGaussian()- 返回 0.0 到 1.0 之间的高斯分布(即正态分布)的 double
  • nextInt() - 返回均匀分布的 int
  • nextInt(int n) - 返回 0 到 n 之间的均匀分布的 int(包括 0,不包括 n)
  • nextLong() - 返回均匀分布的 long
  • setSeed(long seed) - 设置种子

java.util.Random类有两种方式构建方式:

  1. 带种子
  2. 不带种子(类默认使用当前系统时钟作为种子)

只要种子一样,产生的随机数也一样: 因为种子确定,随机数算法也确定,因此输出是确定的。

Java 8 引入了新的 ints 方法,返回一个java.util.stream.IntStream

不带参数的 ints方法将返回一个无限 int 流:

IntStream unlimitedIntStream = random.ints();

调用时还可以指定参数来限制流大小:

IntStream limitedIntStream = random.ints(streamSize);

当然,也可以为生成数值设置最大值和最小值:

IntStream limitedIntStreamWithinARange = random.ints(streamSize, min, max);

3. java.util.concurrent.ThreadLocalRandom工具类

ThreadLocalRandom 是 JDK 7 之后提供,也是继承至 java.util.Random。

每一个线程有一个独立的随机数生成器,用于并发产生随机数,能够解决多个线程发生的竞争争夺。效率更高!

ThreadLocalRandom 不是直接用 new 实例化,而是第一次使用其静态方法 current() 得到ThreadLocal 实例,然后调用 java.util.Random 类提供的方法获得各种随机数。

public class JavaRandom {
 public static void main(String args[]) {
 new MyThread().start();
 new MyThread().start();
 }
}
class MyThread extends Thread {
 public void run() {
 for (int i = 0; i < 2; i++) {
 System.out.println(Thread.currentThread().getName() + ": " + ThreadLocalRandom.current().nextDouble());
 }
 }
}

4. java.util.SplittableRandom

Java 8 还带来了一个快速随机数生成器SplittableRandom类。

正如 JavaDoc 中描述的那样,这是一个支持并行计算的随机数生成器。值得注意的是,这个实例非线程安全。使用该类时需要当心。

现在有了 nextInt 和 ints 方法。调用 nextInt 时,可以通过参数指定 top 和 bottom 范围:

SplittableRandom splittableRandom = new SplittableRandom();
int randomWithSplittableRandom = splittableRandom.nextInt(min, max);

这里也提供了ints方法。这意味着可以轻松得到 int流。

5. java.Security.SecureRandom

此类提供强加密生成器(RNG),也是继承至 java.util.Random。操作系统收集了一些随机事件,比如鼠标点击,键盘点击等等,SecureRandom 使用这些随机事件作为种子。

强加密:
根据rfc 1750 描述:任何传递给secureRandom对象的种子材料必须是不可预知的,所有SecureRandom对象输出的输出序列必须是强加密的。

对象获取:
可通过无参构造或getInstance()方法获得对象

方法:

  • generateSeed(int size);返回给定的种子字节数量
  • getAlgorithm();返回算法名称
  • getInstance();返回实现指定随机数生成器 (RNG) 算法的 SecureRandom 对象。此方法有多个重载方法
  • getProvider();返回算法实现的提供商
  • getSeed();返回给定的种子字节数量
  • next();生成一个包含用户指定伪随机位数的整数(右对齐,带前导零)。
  • nextBytes();生成用户指定的随机字节数
  • setSeed();重新设置此随机对象的种子,有重载方法

支持的随机算法只有一个: SHA1PRNG

使用:

SecureRandom random1 = SecureRandom.getInstance("SHA1PRNG");
SecureRandom random2 = SecureRandom.getInstance("SHA1PRNG");for (int i = 0; i < 5; i++) {
 System.out.println(random1.nextInt() + " != " + random2.nextInt());
}

6. 随机字符串

可以使用 Apache Commons-Lang 包中的 RandomStringUtils 类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值