一.java.lang.Math.Random
调用这个Math.Random()函数能够返回带正号的double值,取值范围是[0.0,1.0)的左闭右开区间,并在该范围内(近似)均匀分布。
二.java.util.Random
-
常用函数
- protected int next(int bits):生成下一个伪随机数。
- boolean nextBoolean():返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的boolean值。
- void nextBytes(byte[] bytes):生成随机字节并将其置于用户提供的 byte 数组中。
- double nextDouble():返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0和1.0之间均匀分布的 double值。
- float nextFloat():返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0和1.0之间均匀分布float值。
- double nextGaussian():返回下一个伪随机数,它是取自此随机数生成器序列的、呈高斯(“正态”)分布的double值,其平均值是0.0标准差是1.0。
- int nextInt():返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的 int 值。
- int nextInt(int n):返回一个伪随机数,它是取自此随机数生成器序列的、在(包括和指定值(不包括)之间均匀分布的int值。
- long nextLong():返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的 long 值。
- void setSeed(long seed):使用单个 long 种子设置此随机数生成器的种子。
-
构造函数
- public Random() 该构造方法使用一个和当前系统时间对应的相对时间有关的数字作为种子数,然后使用这个种子数构造Random对象。
- public Random(long seed) 该构造方法可以通过制定一个种子数进行创建。
-
总结:
- 种子数只是随机算法的起源数字,和生成的随机数字的区间无关;相同种子数的Random对象,相同次数生成的随机数字是完全相同的;
- 生成[0,n)区间的数有公式Math.abs(nextInt()%n)和nextInt(n)
- 生成任意区间[a,b),公式nextInt(b-a)+a和Math.abs(nextInt()%(b-a)+a
- 生成任意区间[a,b],公式nextInt(b+1-a)+a和Math.abs(nextInt()%(b+1-a)+a)
示例代码:
package com.random; import java.util.Random; import org.junit.After; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; public class testRandom { private static Random r1; private static Random r2; /** * @Title: loadUp * @Description: 测试之前的初始化工作 */ @BeforeClass public static void loadUp() { r1 = new Random(10); r2 = new Random(10); } @After public void testAfter() { System.out.println("------------------------>"); } /** * @Title: testMathRandom * @Description: 通过Math.random产生[0,5)之间的数 * @throws */ @Ignore @Test public void testMathRandom() { for (int i = 0; i < 20; i++) { System.out.println((int) (Math.random() * 5)); } } /** * @Title: testTwoRandom * @Description: 两个random对象,具有相同的种子,会产生相同的随机数(伪随机) */ @Test public void testTwoRandom() { for (int i = 0; i < 10; ++i) { Assert.assertEquals(r1.nextInt(), r2.nextInt()); } } /** * @Title: testRandom1 * @Description: 产生[1,2.5)之间的数的,有公式 nextDouble()*(b-a)+a * @param 设定文件 * @return void 返回类型 * @throws */ @Test @Ignore public void testRandom1() { for (int i = 0; i < 10; ++i) { System.out.println(r1.nextDouble() * 1.5 + 1); } } /** * @Title: testRandom2 * @Description: 产生[0,10)的两种方法,生成[0,n)区间的数有公式Math.abs(nextInt()%n)和nextInt(n) */ @Test @Ignore public void testRandom2() { for (int i = 0; i < 10; ++i) { System.out.println("方法一: " + r1.nextInt(10)); System.out.println("方法二: " + Math.abs(r2.nextInt() % 10)); } } /** * @Title: testNextBoolean * @Description: 生成一个随机的boolean值,true和false值均等 */ @Test @Ignore public void testNextBoolean() { for (int i = 0; i < 10; ++i) { System.out.println(r1.nextBoolean()); } } /** * @Title: testNextInt * @Description: 生成一个-2^31~2^31-1之间的随机数 */ @Test @Ignore public void testNextInt() { for (int i = 0; i < 10; ++i) { System.out.println(Math.abs(r1.nextInt()));// 0~2^31-1 System.out.println(r1.nextInt());// -2^31~2^31-1 System.out.println(r1.nextInt(10));// [0,10),参数10为随机生成数字的上限 } } /** * @Title: testNextDouble * @Description: 随机生成[0,1.0)区间的小数 */ @Test @Ignore public void testNextDouble() { for (int i = 0; i < 10; ++i) { System.out.println(r1.nextDouble()); } } /** * @Title: testRandom3 * @Description: 生成任意区间[a,b),公式nextInt(b-a)+a和Math.abs(nextInt()%(b-a)+a),例如区间[-3,15) */ @Test @Ignore public void testRandom3() { for (int i = 0; i < 100; ++i) { System.out.println(r1.nextInt(18) - 3); System.out.println(Math.abs(r1.nextInt()%18)-3); } } /** * @Title: testRandom4 * @Description: 生成任意区间[a,b],公式nextInt(b+1-a)+a和Math.abs(nextInt()%(b+1-a)+a),例如区间[3,10] */ @Test public void testRandom4(){ for(int i=0;i<20;++i){ System.out.println(r1.nextInt(8)+3); } } }
三.可以通过java.util.Random实现几率控制
在前面的方法介绍中,nextInt(int n)方法中生成的数字是均匀的,也就是说该区间内部的每个数字生成的几率是相同的。那么如果生成一个[0,100)区间的随机整数,则每个数字生成的几率应该是相同的,而且由于该区间中总计有100个整数,所以每个数字的几率都是1%。按照这个理论,可以实现程序中的几率问题。
示例代码:
@Test public void testRandom5() { for (int i = 0; i < 100; ++i) { int a = r1.nextInt(100); if (a < 55) { System.out.println("1");// 55%的几率 } else if (a < 95) { System.out.println("2");// 40%的几率 } else { System.out.println("3");// 5%的几率 } } }