前言
提起生成随机数,映像最深的是Math.random()
,它生成一个[0,1)
之间的double
型数据,如需变成整数等,需要自己手动转,非常麻烦;Random
位于java.util
包下,该类提供了很多开箱即用的方法。
Math.random()
/**
* Returns a {@code double} value with a positive sign, greater
* than or equal to {@code 0.0} and less than {@code 1.0}.
* Returned values are chosen pseudorandomly with (approximately)
* uniform distribution from that range.
*
* <p>When this method is first called, it creates a single new
* pseudorandom-number generator, exactly as if by the expression
*
* <blockquote>{@code new java.util.Random()}</blockquote>
*
* This new pseudorandom-number generator is used thereafter for
* all calls to this method and is used nowhere else.
*
* <p>This method is properly synchronized to allow correct use by
* more than one thread. However, if many threads need to generate
* pseudorandom numbers at a great rate, it may reduce contention
* for each thread to have its own pseudorandom-number generator.
*
* @return a pseudorandom {@code double} greater than or equal
* to {@code 0.0} and less than {@code 1.0}.
* @see Random#nextDouble()
*/
public static double random() {
return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}
Random
该类的一个实例用于生成伪随机数流。该类使用一个48位种子,该种子使用线性同余公式进行修改。(参见Donald Knuth,《计算机编程的艺术》,第2卷,第3.2.1节。)
如果用相同的种子创建Random的两个实例,并且对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列。为了保证这个属性,为Random类指定了特定的算法。
为了Java代码的绝对可移植性,Java实现必须为Random类使用这里显示的所有算法。然而,类Random的子类被允许使用其他算法,只要它们遵守所有方法的通用约定。
由Random类实现的算法使用了一个受保护的实用方法,每次调用都可以提供多达32个伪随机生成的位。
许多应用程序会找到数学方法。随机使用更简单。
random的实例是线程安全的。但是,跨线程并发使用相同的java.util.Random实例可能会遇到争用,从而导致性能较差。考虑在多线程设计中使用java.util.concurrent.ThreadLocalRandom。
random的实例不是加密安全的。考虑使用java.security.SecureRandom来获得一个加密安全的伪随机数生成器,供安全敏感的应用程序使用。
Random
提供的方法预览
- 代码示例,生成
[0,max]
之间的整数
/**
* 生成[0, max)之间的随机数
*/
public static Integer nextInt(Integer max) {
Random rd = new Random();
return rd.nextInt(max);
}
Random
实现了Serializable
接口,有SecureRandom
和ThreadLocalRandom
两个子类