设为首页收藏本站联系我们

JAVA中文站

 找回密码
 注册会员

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
JAVA中文站 门户 JAVA文摘 基础知识 查看内容

Java8中的java.util.Random类

2014-3-31 21:16| 发布者: admin| 查看: 4879| 评论: 0|原作者: 踏雁寻花|来自: importnew

摘要: 本文通过示例介绍了Java8中的java.util.Random类及用法。
本文由 ImportNew - 踏雁寻花 翻译自 javacodegeeks。欢迎加入Java小组。转载请参见文章末尾的要求。

Java8中的java.util.Random类

在Java8中java.util.Random类的一个非常明显的变化就是新增了返回随机数流(random Stream of numbers)的一些方法。

下面的代码是创建一个无穷尽的double类型的数字流,这些数字在0(包括0)和1(不包含1)之间。

1
2
Random random = new Random();
DoubleStream doubleStream = random.doubles();

下面的代码是创建一个无穷尽的int类型的数字流,这些数字在0(包括0)和100(不包括100)之间。

1
2
Random random = new Random();
IntStream intStream = random.ints(0, 100);

那么这些无穷尽的数字流用来做什么呢?接下来,我通过一些案例来分析。记住,这些无穷大的数字流只能通过某种方式被截断(limited)。

示例1:创建10个随机的整数流并打印出来:

1
intStream.limit(10).forEach(System.out::println);

示例2:创建100个随机整数:

1
2
3
4
List<Integer> randomBetween0And99 = intStream
                                   .limit(100)
                                   .boxed()
                                   .collect(Collectors.toList());

对于高斯伪随机数(gaussian pseudo-random values)来说,random.doubles()方法所创建的流不能等价于高斯伪随机数,然而,如果用java8所提供的功能是非常容易实现的。

1
2
Random random = new Random();
DoubleStream gaussianStream = Stream.generate(random::nextGaussian).mapToDouble(e -> e);

这里,我使用了Stream.generate api,并传入Supplier 类的对象作为参数,这个对象是通过调用Random类中的方法 nextGaussian()创建另一个高斯伪随机数。

接下来,我们来对double类型的伪随机数流和double类型的高斯伪随机数流做一个更加有意思的事情,那就是获得两个流的随机数的分配情况。预期的结果是:double类型的伪随机数是均匀的分配的,而double类型的高斯伪随机数应该是正态分布的。

通过下面的代码,我生成了一百万个伪随机数,这是通过java8提供的api实现的:

1
2
3
4
5
6
7
8
Random random = new Random();
DoubleStream doubleStream = random.doubles(-1.0, 1.0);
LinkedHashMap<Range, Integer> rangeCountMap = doubleStream.limit(1000000)
    .boxed()
    .map(Ranges::of)
    .collect(Ranges::emptyRangeCountMap, (m, e) -> m.put(e, m.get(e) + 1), Ranges::mergeRangeCountMaps);
 
rangeCountMap.forEach((k, v) -> System.out.println(k.from() + "\t" + v));

代码的运行结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-1      49730
-0.9    49931
-0.8    50057
-0.7    50060
-0.6    49963
-0.5    50159
-0.4    49921
-0.3    49962
-0.2    50231
-0.1    49658
0       50177
0.1     49861
0.2     49947
0.3     50157
0.4     50414
0.5     50006
0.6     50038
0.7     49962
0.8     50071
0.9     49695

为了类比,我们再生成一百万个高斯伪随机数:

1
2
3
4
5
6
7
8
9
10
11
Random random = new Random();
DoubleStream gaussianStream = Stream.generate(random::nextGaussian).mapToDouble(e -> e);
LinkedHashMap<Range, Integer> gaussianRangeCountMap =
    gaussianStream
            .filter(e -> (e >= -1.0 && e < 1.0))
            .limit(1000000)
            .boxed()
            .map(Ranges::of)
            .collect(Ranges::emptyRangeCountMap, (m, e) -> m.put(e, m.get(e) + 1), Ranges::mergeRangeCountMaps);
 
gaussianRangeCountMap.forEach((k, v) -> System.out.println(k.from() + "\t" + v));

上面代码输出的结果恰恰与我们预期结果相吻合,即:double类型的伪随机数是均匀的分配的,而double类型的高斯伪随机数应该是正态分布的。

用伪随机数所得的结果:

用高斯伪随机数所得的结果:

附:完整代码可点击这里获取

原文链接: javacodegeeks 翻译: ImportNew.com 踏雁寻花
译文链接: http://www.importnew.com/9672.html
转载请保留原文出处、译者和译文链接。]

最新评论

QQ|小黑屋|手机版|Archiver|联系我们|JAVA中文站 ( 浙ICP备12034637  

GMT+8, 2017-6-27 03:05 , Processed in 0.569026 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

返回顶部