实例讲解Java中random.nextInt()与Math.random()的基础用法

1、来源

random.nextInt() 为 java.util.Random类中的方法;

Math.random() 为 java.lang.Math 类中的静态方法。

2、用法

产生0-n的伪随机数(伪随机数参看最后注解):

// 两种生成对象方式:带种子和不带种子(两种方式的区别见注解)
Random random = new Random();
Integer res = random.nextInt(n);
Integer res = (int)(Math.random() * n);

3、jdk源码

// random.nextInt(n)
public int nextInt(int n) {
  if (n <= 0)
    throw new IllegalArgumentException("n must be positive");
  if ((n & -n) == n) // i.e., n is a power of 2
    return (int)((n * (long)next(31)) >> 31);
  int bits, val;
  do {
    bits = next(31);
    val = bits % n;
  } while (bits - val + (n-1) < 0);
  return val;
}
// Math.random()
public static double random() {
  Random rnd = randomNumberGenerator;
  // 第一次调用,生成一个随机数生成器
  if (rnd == null) rnd = initRNG();
  return rnd.nextDouble();
}
// 生成的方法为同步的,线程安全
private static synchronized Random initRNG() {
 Random rnd = randomNumberGenerator;
   return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd;
 }
// 该方法为 Random 类中的方法
public double nextDouble() {
  return (((long)(next(26)) << 27) + next(27))
    / (double)(1L << 53);
}

4、小结

  • Math.random() 方法生成[0, 1)范围内的double类型随机数;Random类中的nextXxxx系列方法生成0-n的随机数;
  • Math.random() 线程安全,多线程环境能被调用;
  • 如无特殊需求,则使用(int)(Math.random()*n)的方式生成随机数即可。

5、注:何谓伪随机数

伪随机既有规则的随机,Random类中的随机算法就是伪随机。

具体表现为:相同种子数的Random对象生成的随机数序列相同:

@Test
public void createProjectNo() {
   Random r1 = new Random(100);
   Random r2 = new Random(100);
   for (int i = 0; i < 100; i ++) {
     System.out.println(r1.nextInt(10)+", "+r2.nextInt(10));
   }
 }

结果为:

如不想生成相同的随机数序列,则应只使用一个Random类。而Math类中的随机数生成器 randomNumberGenerator 对象为静态的,可考虑使用。

6、注:Random类的两种构造方法区别

1、源码

public Random() {
 this(seedUniquifier() ^ System.nanoTime());
}
public Random(long seed) {
  if (getClass() == Random.class)
    this.seed = new AtomicLong(initialScramble(seed));
  else {
    // subclass might have overriden setSeed
    this.seed = new AtomicLong();
    setSeed(seed);
  }
}

2、区别

从源码中可以看到,未定义种子的构造方法里,使用当前系统时间相关的一个数字作为种子数,该种子数只作为随机算法的起源数字,与生成的随机数区间无关系。

这篇文章是我对Java中随机数的一些简单的理解,如有不对的地方或者其他的见解欢迎指导。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • Java中Collection、List、Set、Map之间的关系总结

    初学java,单个的接触有点迷糊,所以总结下他们的关系 一.关系 Collection --List:以特定顺序存储 --ArrayList.LinkList.Vector --Set:不能包含重复的元素 --HashSet.TreeSet Map --HashMap.HashTable.TreeMap 二.分别讲解 Collection:Collection是一个父接口,List和Set是继承自他的子接口,Collection是最基本的集合接口,Java SDK中不提供直接继承自Collect

  • 浅谈Java中类的实例化步骤

    就个人的一些看法简单的 谈谈static. 就java 工程师来说,static非常容易在面试的时候被问到. 言归正传,书面上说static是静态的.其实我把它理解为"全局的".什么叫全局的?全局的属性,全局的方法,全局的代码块. 全局属性,全局方法,比较好理解就是这个类所有的对象都共有的属性和方法.因为是整个类共有的,所以可以通过声明直接调用.我把它理解为"单例模式"的属性和方法.所谓单例模式就是指这个类声明的所有对象共享这些属性和方法.一个对象对这个属性进行了修

  • Java基于深度优先遍历的随机迷宫生成算法

    这两天因为要做一个随机的地图生成系统,所以一直在研究随机迷宫生成算法,好吧,算是有一点小小的成果. 随机迷宫生成我自己的理解简而言之分为以下几步: 1.建立一张地图,我用的二维数组表示,地图上全是障碍物.然后再创建一个用来表示每个格子是否被访问过的二维数组.再创建一个用来表示路径的栈结构. 2.随机选择地图上的一点,呃为了方便我初始点直接取的是左上角即坐标表示为0,0的格子.终点的话因为不涉及到交互就暂时没有. 3.查找当前格子的邻接格(注意,这里的邻接格子都是还未被访问的,下面的代码里有写).

  • sqlite数据库的介绍与java操作sqlite的实例讲解

    sqlite是啥? 1.一种轻型数据库 2.关系型数据库 3.占用资源很低,几百K内存,适合嵌入式设备 4.支持windows.linux.unix 5.可与java.php.c#.python等结合 6.处理速度快于mysql 7.不需要配置.不需要安装.不需要管理 8.一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘文件,简单的说一个数据库就是一个单一文件 为啥要用它? 之前的web项目一直用的mysql数据库,因为目前的项目需要做一个桌面应用,可以在不同地方复用的,而我们不能

  • Java中的Map允许有重复元素吗?

    Java中常见的三个集合接口:List.Set.Map,已经知道List中是允许有重复元素的,而Set中是不允许有重复元素的,那么Map中允许有重复元素吗? 查阅资料,发现是不可以的,因为map是无序的,它的查询需要通过key的值来查找,如果你定义两个同样的key,那么一个key就对应了多个值,这样就违背了java对map的定义,键和值是一一对应的.所以key不可以重复. 写个代码测试一下: package com.test.collection; import java.util.HashMa

  • Java全排列算法字典序下的下一个排列讲解

    一直写过数组全排列的算法,当时接触的是使用回溯的方法,这样可以保证生成的全排列一定是按照字典序的,但是今天在做leetcode上的一道题时,问题是要你找到某个排列情况的下一个按照字典序排列的状态. 如果直接一点,大可从头开始做全排列,然后到目标状态时,在做一次即可找到要的状态,但是如果题目给的状态非常靠后,则要花费很大的代价,这样做就显得有些笨拙了. 所以做这道题的时候一直在思考如何按照字典序生成全排列. 假设此时给出的状态时5 2 4 3 1,那么下一个状态要如何确定呢?首先从人的视角来看,绝

  • Java中保留两位小数的四种方法实现实例

    在写程序的时候,有时候可能需要设置小数的位数,那么java中有哪几种保留小数位数的方法呢?本文以两位小数为例给出四种方法. package CodeJava_Leet; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; /** * Created by Yechengpeng on 2016-08-14. */ public class Test { public

  • Java找不到或无法加载主类及编码错误问题的解决方案

    先给出具体代码(当前目录为:D:\pro): package org.test; public class TestJava{ public static void main(String args[]){ System.out.println("Hello World!!!"); System.out.println("你好,Java!!"); } } 1. cmd 窗口运行时出现"找不到或无法加载主类"问题: D:\pro>javac

  • Java动态代理实现方法小结

    本文实例讲述了Java动态代理实现方法.分享给大家供大家参考,具体如下: 静态代理了解的差不多了,但是对于动态代理理解的还不是很通透,这里先把一些常用的动态代理实现方法记录下来,日后时常看看争取早日融会贯通. 1.JDK实现动态代理 主要使用了Proxy.newProxyInstance()方法,该方法的官方解释为:返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序. public interface ISomeService { String doFirst(); vo

  • Java实现n位数字的全排列

    n位数字的全排列共有n!种. 本排列只对字符型数字排列进行输出,输出的是字符型数字.这种问题一般都需要用递归的方法. java代码如下: public class Test { static int k=0; public static void main(String[] args) { int a[]={1,2,3,4,5}; permutations(a,0,4); } public static void permutations(int[]a,int m,int n){ if(m==n

随机推荐