Java使用Random取得一个范围内的随机数问题

如果你也在找一个取得范围内随机数的算法,看看下面的介绍吧。

这次主要说一下Java中的随机数取得函数Random()。

 

以下为本次要介绍的取得范围内随机数的函数。

  /***
     * 取得范围内的随机数
     * @param min
     * @param max
     * @return
     */
    public static int getRandInteger(int min,int max) {
        int rt = 0;
        try {
            Random random = new Random();
            //方法一:
            //rt= random.nextInt(max) % (max - min + 1) + min;
            //方法二:
            rt= random.nextInt(max-min+1)  + min;
            return rt;
        } catch (Exception e) {
            log.error("Get random error:", e);
            return -1;
        }
    }

以上代码可见有两个方法,方法一是我从网上获得的其他网友的方法,这个方法确实也可以取得范围内的随机数。

测试类:

    @Test
    void getRandInteger() {

        HashMap<Integer,Integer> map=new HashMap<Integer, Integer>();
        int sum=0;
        for(int i=0;i<1000;i++)
        {
            Integer r=RandomUtil.getRandInteger(10,40);
            if(map.containsKey(r))
            {
                Integer counter=map.get(r)+1;
                map.put(r,counter);
            }else
            {
                map.put(r,1);
            }
            //System.out.println(RandomUtil.getRandInteger(8,40));
            sum++;
        }

        map=(HashMap<Integer,Integer>)MapDataUtil.sortByKey(map,false);

        map.forEach((k,v)->System.out.println("取得值:"+k.toString()+" --> \t 
                次数:"+v.toString()));
        System.out.println("总计:"+sum);
    }

但经过我测试,这个随机数并不随机,或者说随机的概率并不呈现一个均匀分布,这不是我想要的。

在范围(1,20)时,随机概率还算均匀,如下:

取得值:1 --> 	 次数:55
取得值:2 --> 	 次数:59
取得值:3 --> 	 次数:48
取得值:4 --> 	 次数:40
取得值:5 --> 	 次数:52
取得值:6 --> 	 次数:51
取得值:7 --> 	 次数:56
取得值:8 --> 	 次数:40
取得值:9 --> 	 次数:56
取得值:10 --> 	 次数:46
取得值:11 --> 	 次数:47
取得值:12 --> 	 次数:42
取得值:13 --> 	 次数:42
取得值:14 --> 	 次数:56
取得值:15 --> 	 次数:54
取得值:16 --> 	 次数:42
取得值:17 --> 	 次数:51
取得值:18 --> 	 次数:69
取得值:19 --> 	 次数:51
取得值:20 --> 	 次数:43
总计:1000

但是如果是范围不是从1开始的,如(10,30),结果就不同了,如下:

取得值:10 --> 	 次数:50
取得值:11 --> 	 次数:48
取得值:12 --> 	 次数:48
取得值:13 --> 	 次数:43
取得值:14 --> 	 次数:48
取得值:15 --> 	 次数:48
取得值:16 --> 	 次数:70
取得值:17 --> 	 次数:55
取得值:18 --> 	 次数:47
---------分割线-------
取得值:19 --> 	 次数:20
取得值:20 --> 	 次数:27
取得值:21 --> 	 次数:38
取得值:22 --> 	 次数:26
取得值:23 --> 	 次数:25
取得值:24 --> 	 次数:29
取得值:25 --> 	 次数:21
取得值:26 --> 	 次数:26
取得值:27 --> 	 次数:24
取得值:28 --> 	 次数:27
取得值:29 --> 	 次数:16
取得值:30 --> 	 次数:26
取得值:31 --> 	 次数:28
取得值:32 --> 	 次数:20
取得值:33 --> 	 次数:20
取得值:34 --> 	 次数:19
取得值:35 --> 	 次数:28
取得值:36 --> 	 次数:27
取得值:37 --> 	 次数:30
取得值:38 --> 	 次数:19
取得值:39 --> 	 次数:26
取得值:40 --> 	 次数:21
总计:1000

从上面结果可知,从10-18这个范围取得的概率远大于其他数取得的概率。

这也不是正常意义下的取得随机数,如果程序严谨的话,这是不符合要求的(我又开始认真了.....)

经过我反复测试研究,发现这并不是偶然,如果取数范围为(min,max),那么(min,min+min-1)这个范围内的数取得的概率是远大于其他数的。

这个结果如果你的程序只是要个随机数,概率不要求平均,那这个取得方法是没有问题的

但在某些情况下,比如我要用的场景,不但要取得一个范围的数,还需要概率趋于平均,那就不能用方法1了。

 

介绍一下方法2:

//方法二:
random.nextInt(max-min+1)  + min;

方法2的原理其实是取得【0,max-min】这个范围内的随机数,这个方式,在上面的测试中已经证实还是比较平均的,那如果最小值不是0,那就手动给它+min即可。

看下测试结果:

取得值:10 --> 	 次数:35
取得值:11 --> 	 次数:40
取得值:12 --> 	 次数:31
取得值:13 --> 	 次数:29
取得值:14 --> 	 次数:46
取得值:15 --> 	 次数:38
取得值:16 --> 	 次数:33
取得值:17 --> 	 次数:18
取得值:18 --> 	 次数:30
取得值:19 --> 	 次数:35
取得值:20 --> 	 次数:21
取得值:21 --> 	 次数:41
取得值:22 --> 	 次数:26
取得值:23 --> 	 次数:31
取得值:24 --> 	 次数:28
取得值:25 --> 	 次数:31
取得值:26 --> 	 次数:45
取得值:27 --> 	 次数:35
取得值:28 --> 	 次数:21
取得值:29 --> 	 次数:26
取得值:30 --> 	 次数:27
取得值:31 --> 	 次数:39
取得值:32 --> 	 次数:31
取得值:33 --> 	 次数:37
取得值:34 --> 	 次数:42
取得值:35 --> 	 次数:26
取得值:36 --> 	 次数:36
取得值:37 --> 	 次数:32
取得值:38 --> 	 次数:27
取得值:39 --> 	 次数:30
取得值:40 --> 	 次数:33
总计:1000

第二次测试运行结果:

取得值:10 --> 	 次数:31
取得值:11 --> 	 次数:32
取得值:12 --> 	 次数:30
取得值:13 --> 	 次数:27
取得值:14 --> 	 次数:34
取得值:15 --> 	 次数:27
取得值:16 --> 	 次数:26
取得值:17 --> 	 次数:33
取得值:18 --> 	 次数:30
取得值:19 --> 	 次数:45
取得值:20 --> 	 次数:33
取得值:21 --> 	 次数:37
取得值:22 --> 	 次数:34
取得值:23 --> 	 次数:47
取得值:24 --> 	 次数:34
取得值:25 --> 	 次数:39
取得值:26 --> 	 次数:35
取得值:27 --> 	 次数:32
取得值:28 --> 	 次数:29
取得值:29 --> 	 次数:25
取得值:30 --> 	 次数:37
取得值:31 --> 	 次数:37
取得值:32 --> 	 次数:37
取得值:33 --> 	 次数:30
取得值:34 --> 	 次数:27
取得值:35 --> 	 次数:31
取得值:36 --> 	 次数:28
取得值:37 --> 	 次数:29
取得值:38 --> 	 次数:30
取得值:39 --> 	 次数:35
取得值:40 --> 	 次数:19
总计:1000

两次运行的结果还是比较平均的吧,第一个方法网上说的比较多,应该是在取模的时候造成了分布不均,

方法二其实更简单易懂,使用起来也方便,个人认为还是不错的,如果你有更好的算法,欢迎告知。


简码笔记,让你的代码更加简约精炼。

转载请注明出处。

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简码笔记

您的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值