恕我直言,我怀疑你并不会生成随机数

于是 5 分钟后我写出了下面这段代码:

public class GenerateRandomInteger {

public static void main(String[] args) {

int leftLimit = 2;

int rightLimit = 11;

Random random = new Random();

int range = rightLimit - leftLimit;

Runnable r = () -> {

int generatedInteger = leftLimit + (int)(random.nextFloat() * range);

System.out.println(generatedInteger);

};

for (int i = 1; i < 10; i++) {

new Thread®.start();

}

}

}

无论是调整线程的数量,还是多次重新运行,结果都符合预期,在 2 - 11 之间。

7

2

5

8

6

2

9

9

7

nextFloat() 方法返回一个均匀分布在 0 - 1 之间的随机浮点数(包含 0.0f,但不包含 1.0f),乘以最大值和最小值的差,再强转为 int 类型就可以保证这个随机数在 0 到(最大值-最小值)之间,最后再加上最小值,就恰好可以得到指定范围内的数字。

如果你肯读源码的话,会发现 Random 类有一个 nextInt(int bound) 的方法,该方法会返回一个随机整数,均匀分布在 0 - bound 之间(包含 0,但不包含指定的 bound)。那么利用该方法也可以得到一个有效的随机数,来看示例代码。

public class GenerateRandomNextInt {

public static void main(String[] args) {

int leftLimit = 2;

int rightLimit = 11;

Random random = new Random();

Runnable r = () -> {

int generatedInteger = leftLimit + random.nextInt(rightLimit - leftLimit + 1);

System.out.println(generatedInteger);

};

for (int i = 1; i < 10; i++) {

new Thread®.start();

}

}

}

由于 nextInt() 不包含 bound,因此需要 + 1。程序运行的结果也符合预期:

8

2

9

8

4

6

4

5

7

你看,我之前两次尝试都以失败告终,但我仍然没有放弃希望,经过自己的深思熟虑,我又找到了两种可行的解决办法。这让我想起了普希金的一首诗歌:

假如生活欺骗了你,不要悲伤,不要心急,忧郁的日子里需要镇静,一切都会过去,一切都是瞬息,一切都会过去。希望之火需要再燃,需要呵护,不致让暴风雨将其熄灭,不致让自己在黑暗、阴冷、无助中绝望。

一首好诗吟完之后,我们再来想想还有没有其他的方案。反正我是想到了,Java 7 以后可以使用 ThreadLocalRandom 类,代码示例如下:

public class GenerateRandomThreadLocal {

public static void main(String[] args) {

int leftLimit = 2;

int rightLimit = 11;

Runnable r = () -> {

int generatedInteger = ThreadLocalRandom.current().nextInt(leftLimit, rightLimit +1);

System.out.println(generatedInteger);

};

for (int i = 1; i < 10; i++) {

new Thread®.start();

}

}

}

程序输出的结果如下:

11

9

6

10

6

6

10

7

3

ThreadLocalRandom 类继承自 Random 类,它使用了内部生成的种子来初始化(外部无法设置,所以不能再现测试场景),并且不需要显式地使用 new 关键字来创建对象(Random 可以通过构造方法设置种子),可以直接通过静态方法 current() 获取针对本地线程级别的对象:

static final ThreadLocalRandom instance = new ThreadLocalRandom();

static final void localInit() {

int p = probeGenerator.addAndGet(PROBE_INCREMENT);

int probe = (p == 0) ? 1 : p; // skip 0

long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));

Thread t = Thread.currentThread();

U.putLong(t, SEED, seed);

U.putInt(t, PROBE, probe);

}

public static ThreadLocalRandom current() {

if (U.getInt(Thread.currentThread(), PROBE) == 0)

localInit();

return instance;

}

这样做的好处就是,在多线程或者线程池的环境下,可以节省不必要的内存开销。

最后,我再提供一个解决方案,使用 Apache Commons Math 类库的 RandomDataGenerator 类。在使用该类库之前,需要在 pom.xml 文件中引入该类库的依赖。

org.apache.commons

commons-math3

3.6.1

在需要生成指定范围的随机数时,使用 new RandomDataGenerator() 获取随机生成器实例,然后使用 nextInt() 方法直接获取最大值与最小值之间的随机数。来看示例。

public class RandomDataGeneratorDemo {

public static void main(String[] args) {

int leftLimit = 2;

int rightLimit = 11;

Runnable r = () -> {

int generatedInteger = new RandomDataGenerator().nextInt( leftLimit,rightLimit);

System.out.println(generatedInteger);

};

for (int i = 1; i < 10; i++) {

new Thread®.start();

}

}

}

输出结果如下所示:

8

4

4

4

10

3

10

3

6

结果完全符合我们的预期——这也是我的最后一招,没想到就这么愉快地全交给你了。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最近我根据上述的技术体系图搜集了几十套腾讯、头条、阿里、美团等公司21年的面试题,把技术点整理成了视频(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
n/images/e5c14a7895254671a72faed303032d36.jpg" alt=“img” style=“zoom: 33%;” />

[外链图片转存中…(img-h7VOdQA9-1713686373212)]

最近我根据上述的技术体系图搜集了几十套腾讯、头条、阿里、美团等公司21年的面试题,把技术点整理成了视频(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分

[外链图片转存中…(img-PKFo7JWl-1713686373212)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值