Random类
以下内容摘自“java资源社区”公众号:
https://mp.weixin.qq.com/s?__biz=MzI2NjE1OTMxMw==&mid=2247483797&idx=1&sn=09c2166522b358b27f57dc5c73a98663&chksm=ea93142bdde49d3de5a28681325d3a6b68564ceb47e41e8029c294117bb9112eb9b078ccc5b6&scene=0#rd
在开发中,生成随机数是一个比较常用的功能,比如为一个订单生成一串随机不重复的主键id,或者为某个算法随机生成一组测试数据等等。下面将详细介绍Random类的用法。
一、简介
Random类位于java.util包下,此类的实例用于生成伪随机数流。之所以称之为伪随机,是因为真正意义上的随机数(或者称为随机事件)在某次产生过程中是按照实验过程表现的分布概率随机产生的,其结果是不可预测,不可见的。而计算机中的随机函数是按照一定的算法模拟产生的,其结果是确定的,可见的。我们认为这样产生的数据不是真正意义上的随机数,因而称之为伪随机。
二、Random类的使用
2.1 生成Random对象
Java API中提供了两个构造方法来创建一个Random对象。如下图所示:
无参构造底层调用的也是有参构造,将System.nanoTime()作为参数传递。即如果使用无参构造,默认的seed值为System.nanoTime()。
对于有参构造,需要注意的是,如果seed值相同,不管执行多少次,随机生成的数据是相同的,示例代码如下所示:
package dailytest;
import java.util.Random;
import org.junit.Test;
/**
* Random类学习
* @author yrr
*/
public class RandomTest {
/**
* 使用有参数构造生成Random对象
* 不管执行多少次,每次得到的结果都相同
* -1157793070
* 1913984760
* 1107254586
*/
@Test
public void test01() {
Random random = new Random(10);
for (int i = 0; i < 3; i++) {
System.out.println(random.nextInt());
}
}
}
2.2 Random类中的方法
简单方法如下所示:
package dailytest;
import java.util.Random;
import org.junit.Test;
/**
* Random类学习
* @author yrr
*/
public class RandomTest {
/**
* 测试Random类中的简单方法
*/
@Test
public void test02() {
Random random = new Random();
//随机生成一个整数,这个整数的范围就是int类型的范围-2^31~2^31-1
System.out.println("nextInt():" + random.nextInt());
//随机生成long类型范围的整数
System.out.println("nextLong():" + random.nextLong());
System.out.println("nextDouble():" + random.nextDouble());
byte[] byteArr = new byte[10];
//随机生成byte,并存放在定义的数组中,生成的个数等于定义的数组的个数
random.nextBytes(byteArr);
for (int i = 0; i < byteArr.length; i++) {
System.out.println(byteArr[i]);
}
//nextInt(n),生成范围[0,n)的整数
//随机生成一个整数,整数范围[0,10)
System.out.println("nextInt(10):" + random.nextInt(10));
}
}
对于nextInt(n)方法,我们可以做以下扩展,比如:
package dailytest;
import java.util.Random;
import org.junit.Test;
/**
* Random类学习
* @author yrr
*/
public class RandomTest {
/**
* nextInt(n)的扩展
* 1.生成[0,n]的整数:random.nextInt(n+1)
* 2.生成[m,n]的整数 n>m
* random.nextInt(n-m+1) + m
* 3.生成(m,n)的整数 n>m
* 等价于[m-1,n-1]
* random.nextInt(n-m+1) + m - 1
**/
@Test
public void test03() {
Random random = new Random();
for (int i = 0; i < 3; i++) {
//这里有坑,要注意,如果前面用了+号,应该要把计算结果整体用括号括起来,不然它会把+号解释为字符串拼接..
System.out.println(我生成了一个[3,15)区间的数,它是:" + (random.nextInt(12) + 3));
}
}
}
JDK1.8新增方法:
了解这些新增方法,需要对Stream有学习过,建议可以先学习下1.8的新特性可以帮助理解。也可以先简单了解下用法就可以了。
package dailytest;
import java.util.Random;
import org.junit.Test;
/**
* Random类学习
* @author yrr
*/
public class RandomTest {
/**
* 测试Random类中 JDK1.8提供的新方法
* JDK1.8新增了Stream的概念
* 在Random中,为double, int, long类型分别增加了对应的生成随机数的方法
* 鉴于每种数据类型方法原理是一样的,所以,这里以int类型举例说明用法
**/
@Test
public void test04() {
Random random = new Random();
random.ints(); //生成无限个int类型范围内的数据,因为是无限个,这里就不打印了,会卡死的......
random.ints(10, 100); //生成无限个[10,100)范围内的数据
//生成10个int范围类的个数
int[] arr = random.ints(10).toArray();//这里的toArray 是Stream里提供的方法
System.out.println(arr.length);
for (int i = 0; i < arr.length; i++)
System.out.println(arr[i]);
random.ints(5, 10, 100).forEach(System.out :: println);
//这句话等价于:
arr = random.ints(5, 10, 100).toArray();
for (int i = 0; i < arr.length; i++)
System.out.println(arr[i]);
//对于random.ints();和random.ints(ori, des);
//我们通常采取截断的操作来获取一定个数的随机数
//limit(n)表示限制生成个数为n个
//如生成10个int范围内的整数
random.ints().limit(10).forEach(System.out :: println);
//生成5个[10,100)区间内的整数
random.ints(10, 100).limit(5).forEach(System.out :: println);
}
}
扩展内容:
在JDK1.5版本以前,对于有参构造函数,默认的seed用的是System.currentTimeMillis()。这里简单说明下System.nanoTime()与System.currentTimeMillis()的区别。System.currentTimeMillis()产生一个当前的毫秒,这个毫秒是自1970年1月1日0时起到当前的毫秒数。而System.nanoTime()是从某个不确定的时间起(同一个的虚拟机上起始时间是固定的),到当前的时间差,它精确到纳秒,这个不确定的起始时间可以是未来,如果起始时间是未来,得到的就是个负数。它的主要用途是衡量一个时间段,比如说一段代码所执行的时间。
浙公网安备 33010602011771号