概述
Random类中实现的随机算法是伪随机,也就是有规则的随机。在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要的随机数字。
种子数只是随机算法的起源数字,和生成的随机数字的区间无关
相同种子数的Random对象,相同次数生成的随机数字是完全相同的。也就是说,两个种子数相同的Random对象,第一次生成的随机数字完全相同,第二次生成的随机数字也完全相同。这点在生成多个随机数字时需要特别注意。
方法
构造方法
//会根据当前时间的纳秒值和固定算法生产一个种子数,在调用下一个构造方法
public Random() {}
//利用传入数作为种子数
public Random(long seed) {}
//重新设置Random的种子数,这样就和new Random(long seed)产生的对象一样
synchronized public void setSeed(long seed) {}
//该方法输出的1,2,4的随机数串是一样的,因为他们的种子数(seed)是一样的
//如果想避免出现随机数字相同的情况,则需要注意,无论项目中需要生成多少个随机数字,都只使用一个Random对象即可。
@Test
public void test3() {
Random random = new Random(10);
for (int i = 0; i < 100; i++) {
System.out.print(random.nextInt());
}
System.out.println("-------------------------");
Random random2 = new Random(10);
for (int i = 0; i < 100; i++) {
System.out.print(random2.nextInt());
}
System.out.println("-------------------------");
Random random3 = new Random(100);
for (int i = 0; i < 100; i++) {
System.out.print(random3.nextInt());
}
System.out.println("-------------------------");
random3.setSeed(10);
for (int i = 0; i < 100; i++) {
System.out.print(random3.nextInt());
}
}
返回随机数
//生成随机字节并将它们放入用户提供的字节数组中。
//如果Random对象是同一个,则根据概述中的加粗内容,可知每次调用的此方法返回的数组是固定的
public void nextBytes(byte[] bytes) {}
//返回一个随机的int值,-2^31到2^31-1
public int nextInt(){}
//返回一个随机的int值,上限位bound,介于[0,bound)之间
//如果想生成指定区间的int值,也需要进行一定的数学变换,具体可以参看下面的使用示例中的代码。
public int nextInt(int bound) {}
//返回一个随机的long值,因为Random类只有48位的种子,所有该方法不会返回所有可能的long值。
public long nextLong(){}
//返回一个随机的boolean值
public boolean nextBoolean() {}
//返回一个随机的float,介于[0.0,1.0)之间
public float nextFloat() {}
//返回一个随机的double,介于[0.0,1.0)之间
public double nextDouble(){}
//下一个伪随机数,高斯(“正常”)分布 double值,平均值为 0.0 ,标准差 1.0为该随机数发生器序列
//不知道是什么鬼
public double nextGaussian(){}
返回随机数流
//返回一个流,产生给定的streamSize数量的伪int数int值。产生方式和nextInt()一样
public IntStream ints(long streamSize) {}
//返回一个有效的无限流的伪int值。
public IntStream ints() {}
//返回streamSize长度的,范围在[randomNumberOrigin,randomNumberBound)之间的int流
public IntStream ints(long streamSize, int randomNumberOrigin,int randomNumberBound) {}
//返回一个有效的无限流的伪随机int值,范围在[randomNumberOrigin,randomNumberBound)之间
public IntStream ints(int randomNumberOrigin, int randomNumberBound) {}
//返回一个流,产生给定的streamSize数long数值,产生方式和nextLong()一样
public LongStream longs(long streamSize){}
public LongStream longs() {}
public LongStream longs(long streamSize, long randomNumberOrigin,long randomNumberBound) {}
publ ic LongStream longs(long randomNumberOrigin, long randomNumberBound) {}
//返回一个流,产生给定的streamSize数double值,产生方式和nextDouble()一样
public DoubleStream doubles(long streamSize){}
public DoubleStream doubles() {}
public DoubleStream doubles(long streamSize, double randomNumberOrigin,double randomNumberBound) {}
public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {}
例子
@Test
public void test6() {
Random r = new Random(10);
// 生成[0,1.0)区间的小数
double d1 = r.nextDouble();
// 生成[0,5.0)区间的小数
double d2 = r.nextDouble() * 5;
// 生成任意非从0开始的小数区间[d1,d2)范围的随机数字(其中d1不等于0),则只需要首先生成[0,d2-d1)区间的随机数字,然后将生成的随机数字区间加上d1即可。
// 生成[1,2.5)区间的小数
double d3 = r.nextDouble() * 1.5 + 1;
// 生成任意整数
int n1 = r.nextInt();
// 生成[0,10)区间的整数,两种方法
int n2 = r.nextInt(10);
n2 = Math.abs(r.nextInt() % 10);
// 生成[0,10]区间的整数,相对于整数区间,[0,10]区间和[0,11)区间等价,所以即生成[0,11)区间的整数。
int n3 = r.nextInt(11);
n3 = Math.abs(r.nextInt() % 11);
// 生成[-3,15)区间的整数
int n4 = r.nextInt(18) - 3;
n4 = Math.abs(r.nextInt() % 18) - 3;
}
几率问题
/**
* 按照一定的几率实现程序逻辑也是随机处理可以解决的一个问题。下面以一个简单的示例演示如何使用随机数字实现几率的逻辑。
*
* 在前面的方法介绍中,nextInt(int n)方法中生成的数字是均匀的,也就是说该区间内部的每个数字生成的几率是相同的。
* 那么如果生成一个[0,100)区间的随机整数,则每个数字生成的几率应该是相同的,而且由于该区间中总计有100个整数,
* 所以每个数字的几率都是1%。按照这个理论,可以实现程序中的几率问题。
*
* 随机生成一个整数,该整数以55%的几率生成1,以40%的几率生成2,以5%的几率生成3
*/
@Test
public void test7() {
Random r = new Random(10);
int n5 = r.nextInt(100);
int m; // 结果数字
if (n5 < 55) { // 55个数字的区间,55%的几率
m = 1;
} else if (n5 < 95) {// [55,95),40个数字的区间,40%的几率
m = 2;
} else {
m = 3;
}
}
@Test
public void test8() {
// 关于Math类中的random方法,
//Math类中的random方法就是直接调用Random类中的nextDouble方法实现的。
Math.random();
}