一、Random

1.1 概述

Random类中实现的随机算法是伪随机,也就是有规则的随机,实际上就是一个数字(seed)经过运算后近似随机数的数字。所以实际上伪随机是完全可以通过运算预测的。Java中的随机数种子若不填写就会使用缺省值,即系统时间。

1.2 构造函数

  • 无参构造函数 public Random()

该构造方法使用一个和当前系统时间对应的相对时间有关的数字作为种子 数,然后使用这个种子数构造Random对象。

  • 有参构造函数 public Random(long seed)

该构造方法可以通过给定的种子进行创建。需要说明的是:你在创建一个 Random对象的时候可以给定任意一个合法的种子数,种子数只是随机算法 的起源数字,和生成的随机数的区间没有任何关系。

1.3 方法摘要

  • 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 种子设置此随机数生成器的种子。

    1.4 使用示例

  1. 生成 [0, 1.0) 区间的小数 random.nextDouble()
  2. 生成 [0, 5.0) 区间的小数 random.nextDouble() * 5
  3. 生成 [1.0, 2.5) 区间的小数 random.nextDouble() * 1.5 + 1
  4. 生成-231到231-1之间的整数 random.nextInt()
  5. 生成任意的整数 random.nextInt()
  6. 生成 [0, 10) 之间的整数 random.nextInt(10)

    二、Math

    2.1 随机数相关

    生成一个[0,1)的随机数,用:Math.random()

生成一个[n,m]范围内的随机数,用:Math.floor(Math.random()*(m-n)+n)

生成一个[n,m]范围内且包含n和m的随机数,用:Math.floor(Math.random()*(m-n+1)+n))

System.out.println(Math.random()); // [0, 1)的double类型的数
System.out.println(Math.random() 2);//[0, 2)的double类型的数
System.out.println(Math.random()
2 + 1);// [1, 3)的double类型的数

2.2 其他函数介绍

2.2.1 算术计算

  • Math.sqrt() : 计算平方根
  • Math.cbrt() : 计算立方根
  • Math.pow(a, b) : 计算a的b次方
  • Math.max( , ) : 计算最大值
  • Math.min( , ) : 计算最小值
  • Math.abs() : 取绝对值 ``` System.out.println(Math.sqrt(16)); // 4.0 System.out.println(Math.cbrt(8)); // 2.0 System.out.println(Math.pow(3, 2)); // 9.0 System.out.println(Math.max(2.3, 4.5));// 4.5 System.out.println(Math.min(2.3, 4.5));// 2.3

/**

  • abs求绝对值 */ System.out.println(Math.abs(-10.4)); // 10.4 System.out.println(Math.abs(10.1)); // 10.1 ```

    2.2.2 进位

  • Math.ceil(): 天花板的意思,就是逢余进一
  • Math.floor() : 地板的意思,就是逢余舍一,这个方法会有精度问题,慎用
  • Math.rint(): 四舍五入,返回double值。注意.5的时候会取偶数
  • Math.round(): 四舍五入,float时返回int值,double时返回long值 ``` /**
  • ceil天花板的意思,就是逢余进一 */ System.out.println(Math.ceil(-10.1)); // -10.0 System.out.println(Math.ceil(10.7)); // 11.0 System.out.println(Math.ceil(-0.7)); // -0.0 System.out.println(Math.ceil(0.0)); // 0.0 System.out.println(Math.ceil(-0.0)); // -0.0 System.out.println(Math.ceil(-1.7)); // -1.0

System.out.println(“—————————-“);

/**

  • floor地板的意思,就是逢余舍一 */ System.out.println(Math.floor(-10.1)); // -11.0 System.out.println(Math.floor(10.7)); // 10.0 System.out.println(Math.floor(-0.7)); // -1.0 System.out.println(Math.floor(0.0)); // 0.0 System.out.println(Math.floor(-0.0)); // -0.0

System.out.println(“—————————-“);

/**

  • rint 四舍五入,返回double值 注意.5的时候会取偶数 异常的尴尬=。= */ System.out.println(Math.rint(10.1)); // 10.0 System.out.println(Math.rint(10.7)); // 11.0 System.out.println(Math.rint(11.5)); // 12.0 System.out.println(Math.rint(10.5)); // 10.0 System.out.println(Math.rint(10.51)); // 11.0 System.out.println(Math.rint(-10.5)); // -10.0 System.out.println(Math.rint(-11.5)); // -12.0 System.out.println(Math.rint(-10.51)); // -11.0 System.out.println(Math.rint(-10.6)); // -11.0 System.out.println(Math.rint(-10.2)); // -10.0

System.out.println(“—————————-“); /**

  • round 四舍五入,float时返回int值,double时返回long值 */ System.out.println(Math.round(10)); // 10 System.out.println(Math.round(10.1)); // 10 System.out.println(Math.round(10.7)); // 11 System.out.println(Math.round(10.5)); // 11 System.out.println(Math.round(10.51)); // 11 System.out.println(Math.round(-10.5)); // -10 System.out.println(Math.round(-10.51)); // -11 System.out.println(Math.round(-10.6)); // -11 System.out.println(Math.round(-10.2)); // -10
  1. 【注意】这里有一个非常需要注意的一点是:这里所有进位的方法的入参都要保证是float或者double类型,否则进位方法将毫无意义。例如如下我们经常犯的错误:

int a = 1300, b = 1000; System.out.println(Math.ceil(a / b)); // 1 表达式A(错误使用) System.out.println(Math.ceil(a / (float)b)); // 2 表达式B(正确使用)

  1. <a name="G228Z"></a>
  2. ## 三、工具类
  3. - api 列表
  4. ```kotlin
  5. getRandom :获取 Random
  6. getRandomForIntegerUnbounded :随机数生成无边界的Int
  7. getRandomForIntegerBounded :生成有边界的Int
  8. getRandomForIntegerBounded2 :使用TreadLocalRandom来生成有边界的Int,包含min而不包含max
  9. getRandomForLongUnbounded :随机数生成无边界的Long
  10. getRandomForLongBounded :使用Random生成有边界的Long
  11. getRandomForLongBounded2 :使用ThreadLocalRandom生成有边界的Long
  12. getRandomForFloat0To1 :随机数Float的生成, 随机数Float生成[0.0-1.0)之间的Float随机数
  13. getRandomForFloatBounded :随机数Float的生成, 随机数Float的生成生成[min,max)之间的Float随机数
  14. getRandomForDouble0To1 :随机数Double的生成,生成0.0d-1.0d之间的Double随机数
  15. getRandomForDoubleBounded :随机数Double的生成,生成[min,max)之间的Double随机数
  16. getRandomForDoubleBounded2:使用ThreadLocalRandom生成有边界的Double随机数
  • 工具类源码 ``` object RandomUtils {

    fun getRandom(): Random {

    1. return Random()

    }

    /**

    • 随机数Int的生成,随机数生成无边界的Int */ fun getRandomForIntegerUnbounded(): Int { return getRandom().nextInt() }

      /**

    • 生成有边界的Int
    • @param min
    • @param max
    • @return / fun getRandomForIntegerBounded(min: Int, max: Int): Int { return min + (Random().nextFloat() (max - min)).toInt() }

      /**

    • 使用TreadLocalRandom来生成有边界的Int,包含min而不包含max
    • @param min
    • @param max
    • @return */ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) fun getRandomForIntegerBounded4(min: Int, max: Int): Int { return ThreadLocalRandom.current().nextInt(min, max) }

      /**

    • 随机数生成无边界的Long */ fun getRandomForLongUnbounded(): Long { return Random().nextLong() }

      /**

    • 使用Random生成有边界的Long
    • 因为Random类使用的种子是48bits,所以nextLong不能返回所有可能的long值,long是64bits。
    • @param min
    • @param max
    • @return / fun getRandomForLongBounded(min: Long, max: Long): Long { return min + (Random().nextDouble() (max - min)).toLong() }

      /* 使用ThreadLocalRandom生成有边界的Long

    • @param min
    • @param max
    • @return */ @RequiresApi(Build.VERSION_CODES.LOLLIPOP) fun getRandomForLongBounded4(min: Long, max: Long): Long { return ThreadLocalRandom.current().nextLong(min, max) }

      /**

    • 随机数Float的生成, 随机数Float生成[0.0-1.0)之间的Float随机数 */ fun getRandomForFloat0To1(): Float { return Random().nextFloat() }

      /**

    • 随机数Float的生成, 随机数Float的生成生成[min,max)之间的Float随机数 / fun getRandomForFloatBounded(min: Float, max: Float): Float { return min + Random().nextFloat() (max - min) } // 使用ThreadLocalRandom生成有边界的Float随机数 // ThreadLocalRandom类没有提供 /**
    • 随机数Double的生成,生成0.0d-1.0d之间的Double随机数 */ fun getRandomForDouble0To1(): Double { return Random().nextDouble() }

      /**

    • 随机数Double的生成,生成[min,max)之间的Double随机数 / fun getRandomForDoubleBounded(min: Double, max: Double): Double { return min + Random().nextDouble() (max - min) }

      /* 使用ThreadLocalRandom生成有边界的Double随机数

    • @param min
    • @param max
    • @return */ @RequiresApi(Build.VERSION_CODES.LOLLIPOP) fun getRandomForDoubleBounded4(min: Double, max: Double): Double { return ThreadLocalRandom.current().nextDouble(min, max) }

} ```

四、参考

Java中Random的用法
Java随机数总结
Java中Math函数的使用
高并发情况下你还在用Random生成随机数?
《 面试又挂了》这次竟然和 Random 有关……
Java-随机数工具类