Java中产生随机数的方法有两种:
第一种:Math.random()
第二种:new Random()
一、java.lang.Math.Random:
调用这个Math.Random()函数能够返回带正号的double值,取值范围是[0.0,1.0),在该范围内(近似)均匀分布。因为返回值是double类型的,小数点后面可以保留15位小数,所以产生相同的可能性非常小,在这一定程度上是随机数。
二、java.util.Random:
Random r1 = new Random();
Random r2 = new Random();
Random r3 = new Random(10);
Random r4 = new Random(10);
下面Random()的两种构造方法:
Random():使用一个和当前系统时间对应的相对时间有关的数字作为种子数。
Random(long seed):直接传入一个种子数。
种子的作用是什么?
种子就是产生随机数的第一次使用值,机制是通过一个函数,将这个种子的值转化为随机数空间中的某一个点上,并且产生的随机数均匀的散布在空间中。以后产生的随机数都与前一个随机数有关。
举例:
Random r =new Random(100);
System.out.println(r.nextInt(20));
种子数只是随机算法的起源数字,和生成的随机数字的区间没有任何关系。
初始化时100并没有起直接作用(注意:不是没有起作用),r.nextInt(20)中的20是随机数的上限,产生的随机数为0-20的整数,不包括20。
举例:
Random r1 = new Random();
Random r2 = new Random();
//无参构造使用的是参数作为种子数
Random r3 = new Random(100);
Random r4 = new Random(100);
//产生随机数调用nextXXX()方法
System.out.println(r1.nextInt(10));
System.out.println(r1.nextInt(10));
System.out.println(r2.nextInt(10));
System.out.println(r2.nextInt(10));
System.out.println("-----------------");
System.out.println(r3.nextInt(10));
System.out.println(r3.nextInt(10));
System.out.println(r4.nextInt(10));
System.out.println(r4.nextInt(10));
结果:
5
1
4
0
-----------------
5
0
5
0
------------------------------------------------------------------------------------------------
5
1
4
0
-----------------
5
0
5
0
常见的随机数使用场景及生成方法
(注意值的闭包区间)
1、获取指定数值内的随机数
例2:
//获取[0,n)之间的一个随机整数
public static int getRandom(int n) {
return (int) (Math.random() * n);
}
2、获取2个数字区间内的随机数
例3:
//获取[m,n]之间的随机数(0<=m<=n)
public static int getRandomBetweenNumbers(int m,int n){
return (int)(m + Math.random() * (n - m + 1));
}
此方法可用于生成随机验证码。
3、获取指定长度的随机字符串
Java本身并没有生成随机字符串的方法,但我们可以通过java自带的随机数方法运算获取所需的随机字符串。
例4:
//获取指定位数的随机字符串(包含小写字母、大写字母、数字,0<length)
public static String getRandomString(int length) {
//随机字符串的随机字符库
String KeyString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
StringBuffer sb = new StringBuffer();
int len = KeyString.length();
for (int i = 0; i < length; i++) {
sb.append(KeyString.charAt((int) Math.round(Math.random() * (len - 1))));
}
return sb.toString();
}
在这个例子中,我们先自定义一个字符串库KeyString ,然后通过Math.random()方法获取KeyString长度内的一个随机数,接着再获取该随机数对应KeyString中相应位置的一个字符,最后将随机获取并组装好的字符串返回。
大家可以发现,这个例子获取的随机字符串可能包含小写字母、大写字母、数字;如果说还需要包含其它字符的话,如%、#、/、* 等特殊字符,只需将相应字符添加到字符串库KeyString 中去即可;同理,若想生成只包含小写字母或者只包含数字的字符串,也只需修改字符串库KeyString 即可。可以说,这几乎是获取随机字符串的一个“万金油”方法。
4、随机生成指定概率的数字
获取指定值内的随机数,从理论上来说,每个数字出现概率都是一样的,但是,我们可以通过一定的运算实现按一定的概率获取数字。
如:我们想随机生成0、1这两个数字,但是呢,我们希望0出现的概率为70%,1出现的概率为30%;这个时候,我们可以通过用一定的随机数区间值来分别表示0、1,从而实现按概率获取随机数。
例5:
//输出0或者1;0出现的概率为70%,1出现的概率为30%
public class TestRandom {
public static void main(String[] args){
Random random = new Random();
int n = random.nextInt(100);
if(n < 70){
System.out.println("0");
}else{
System.out.println("1");
}
}
}
由以上示例可知,通过一定的运算,我们就可以按一定概率获取数字,非常简单的抽奖小游戏就可以使用这种方式来设置中奖概率。
例6:
//简单的按概率获取数字,注意定义数组时的概率总和需为100%
public class TestRandom {
public static void main(String[] args) {
//各数字出现的概率分别是:1(10%)、2(20%)、3(30%)、4(40%)
float[][] array = new float[][]{{1,10},{2,20},{3,30},{4,40}};
int n = luckDraw(array,new Random());
if(1 == n){
System.out.println("一等奖");
}else if(2 == n){
System.out.println("二等奖");
}else if(3 == n){
System.out.println("三等奖");
}else if(4 == n){
System.out.println("谢谢参与");
}
}
//简单幸运抽奖
public static int luckDraw(float[][] array,Random random){
int n = 10000; //总值
int length = array.length;
int random_num = random.nextInt(n); //随机数
for(int i=0;i<length;i++){
float before_chance = 0; //当前概率值之前的总概率
for(int j=0;j<i;j++){
before_chance = before_chance + array[j][1];
}
int value = (int) (array[i][1] / 100 * n); //区间
int up = (int) (before_chance / 100 * n); //大于等于该值
int under = up + value; //小于该值
if((up <= random_num) && (random_num < under)){
return (int) array[i][0];
}
}
return 0;
}
}
需要指出的是,这只是一个非常简单的小示例,只适用于要求较低的场景。真正严格意义上的抽奖有许多要求,如总出奖数量、每个奖的概率随时间的推移而变化等,有专门的一些算法去实现抽奖中的各种概率问题,感兴趣的朋友可以去了解一下。
0
-----------------
5
0
5
0