Java书签 #用Java生成指定位数不重复随机数

楔子:或许我一次恋爱都不曾体验就老了。我可能无法和任何人恋爱。我可能一辈子都不会知道恋爱是什么。虽然我的大脑知道念念不忘某个人并为他哭泣、痛苦的感觉,比什么都不知道的要好,可是我的大脑并没有教我如何才能恋爱。- 宫部美雪《理由》

 

1.今日书签

Java生成随机数。
Java生成指定位数不重复随机数。

 

2.风花雪月

2.1.随机数生成方法

Java 中常见的随机数的生成方式有三种:

第一种:通过 Math.random() 返回一个0(包含)到1(不包含)之间的 double 值。
第二种:通过 Random 类来产生一个随机数。
第三种:通过 System.currentTimeMillis() 来获取一个当前时间毫秒数的 long 型数字。

代码示例参考在文末

 

2.3.指定位数随机数

通过以上三种方式,可演变的使用Java生成指定位数随机数的方式就有很多种,下面来扩列两种且小而巧的方法:

2.3.1.使用 Math.random() 生成指定位数随机数

比如生成指定8位随机数,可以像下面一样改造一下:

int randomNum = (int) ((Math.random() * 9 + 1) * 10000000);

注:参数 10000000 可以控制随机数位数,10000000 这样出来8位数,100000 这样出来6位数。

注:(int) (Math.random() * 100 + 1) (int) (Math.random() * 101的区别:

  • Math.random() * 100 + 1:产生1~100之间的随机整数(包括1和100)
  • Math.random() * 101      :产生0~100之间的随机整数(包括0和100)

测试结果:重复率比较高。

随机生机8位数,100000次测试,生成不重复个数:99948,重复个数:52 

 

2.3.2.使用 new Random() 生成指定位数随机数

用 new Random().nextInt(); 可能会出现负数或较指定位数不够的情况。可以像下面一样改造一下补齐:

String randomNum = String.format("%010d", Math.abs(new Random().nextInt()));

随机示例:

    public static void main(String[] args) {
        String randomNum;
        List<String> numList1 = new ArrayList<>();
        List<String> numList2 = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            randomNum = String.format("%010d", Math.abs(new Random().nextInt()));
            if (numList1.contains(randomNum)) {
                numList2.add(randomNum);
            } else {
                numList1.add(randomNum);
            }
        }

        System.out.println("随机生机10位数,100000次测试,生成不重复个数:" + numList1.size() + ",重复个数:" + numList2.size());
    }

注:String 占位表达格式中:0代表前面要补的字符,10代表字符串长度,d表示参数为整数类型。

测试结果:随机生成10万个随机数有点慢

随机生机10位数,100000次测试,生成不重复个数:99998,重复个数:2

100000个随机10位数,2个重复。但一般场景够用了。


Java随机数测试示例:

public class RandomTest {

    public static void main(String[] args) {

        // 通过Math.random()来获取随机数
        testMathRandom();
        System.out.println();

        // 通过默认构造方法构造Random类来获取随机数
        testNewRandom(new Random(), "通过默认构造方法构造Random类");
        // 通过指定种子数字构造Random类来获取随机数
        testNewRandom(new Random(1000), "通过指定种子数字构造Random类第一次");
        testNewRandom(new Random(1000), "通过指定种子数字构造Random类第二次");
        System.out.println();

        // 通过System.currentTimeMillis()来获取随机数
        testCurrentTimeMillis();
    }

    private static void testMathRandom() {
        // 通过Math的random()函数返回一个double类型随机数,范围[0.0, 1.0)
        double random1 = Math.random();
        System.out.println("通过 Math.random() 获取到随机数:" + random1);

        // 通过d获取一个[0, 100)之间的整数
        int random2 = (int) (random1 * 100);
        System.out.println("通过 Math.random() 获取到指定范围的随机数:" + random2);
    }

    private static void testNewRandom(Random random, String marker) {
        // 获取随机的boolean值
        boolean nextBoolean = random.nextBoolean();
        // 获取随机的Double值,范围[0.0, 1.0)
        double nextDouble = random.nextDouble();
        // 获取随机的float值,范围[0.0, 1.0)
        float nextFloat = random.nextFloat();
        // 获取随机的int值
        int nextInt = random.nextInt();
        // 获取随机的[0,100)之间的int值
        int nextIntBound = random.nextInt(100);
        // 获取随机的高斯分布的double值
        double nextGaussian = random.nextGaussian();
        // 获取随机的long值
        long nextLong = random.nextLong();

        // 通过Math的random()函数返回一个double类型随机数,范围[0.0, 1.0)
        double random1 = Math.random();
        System.out.printf("%s获取到的随机数:\r\n" +
                        "boolean值:%s,Double值:%s,Float值:%s,int值:%s," +
                        "int Bound值:%s,Gaussian double值:%s,long值:%s",
                marker, nextBoolean, nextDouble, nextFloat,
                nextInt, nextIntBound, nextGaussian, nextLong);

        System.out.println();
    }

    private static void testCurrentTimeMillis() {
        // 通过System.currentTimeMillis()来获取一个当前时间毫秒数的long型数字
        Long randomNum1 = System.currentTimeMillis();
        System.out.println("通过 System.currentTimeMilliss() 获取到随机长整数:" + randomNum1);

        // 获取一个[0, 100)之间的整数
        // 获取一个当前时间毫秒数的long型数字,取模之后即可得到所需范围内的随机数
        int randomNum2 = (int) (randomNum1 % 100);
        System.out.println("通过 System.currentTimeMilliss() 获取到指定范围的随机数:" + randomNum2);
    }
}

测试结果:

通过 Math.random() 获取到随机数:0.36249263252080566
通过 Math.random() 获取到指定范围的随机数:36

通过默认构造方法构造Random类获取到的随机数:
boolean值:true,Double值:0.15312096796280816,Float值:0.068893015,int值:1956732642,int Bound值:16,Gaussian double值:0.4268972545430564,long值:-2862893424168180428
通过指定种子数字构造Random类第一次获取到的随机数:
boolean值:true,Double值:0.24691546819860266,Float值:0.46028805,int值:-230127712,int Bound值:49,Gaussian double值:-0.5712614462078893,long值:8222391730744523982
通过指定种子数字构造Random类第二次获取到的随机数:
boolean值:true,Double值:0.24691546819860266,Float值:0.46028805,int值:-230127712,int Bound值:49,Gaussian double值:-0.5712614462078893,long值:8222391730744523982

通过 System.currentTimeMilliss() 获取到随机长整数:1587091175269
通过 System.currentTimeMilliss() 获取到指定范围的随机数:69

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值