在Java8中java.util.Random類的一個非常明顯的變化就是新增了傳回随機數流(random Stream of numbers)的一些方法。 下面的代碼是建立一個無窮大的double類型的數字流,這些數字在0(包括0)和1(不包含1)之間。
Random random = new Random();
DoubleStream doubleStream = random.doubles();
下面的代碼是建立一個無窮大的int類型的數字流,這些數字在0(包括0)和100(不包括100)之間。
Random random = new Random();
IntStream intStream = random.ints(0, 100);
那麼這些無窮大的數字流用來做什麼呢?接下來,我通過一些案例來分析。記住,這些無窮大的數字流隻能通過某種方式被截斷(limited)。
示例1:建立10個随機的整數流并列印出來:
intStream.limit(10).forEach(System.out::println);
示例2:建立100個随機整數:
List<Integer> randomBetween0And99 = intStream
.limit(100)
.boxed()
.collect(Collectors.toList());
對于高斯僞随機數( gaussian pseudo-random values )來說,沒有等價于 random.doubles() 方法所建立的流,然而,如果用java8所提供的功能是非常容易實作的。
Random random = new Random();
DoubleStream gaussianStream = Stream.generate(random::nextGaussian).mapToDouble(e -> e);
這裡,我使用了 Str eam.generate api,并傳入 Supplier 類的對象作為參數,這個對象是通過調用Random類中的方法 nextGaussian() 建立另一個高斯僞随機數。 接下來,我們來對double類型的僞随機數流和double類型的高斯僞随機數流做一個更加有意思的事情,那就是獲得兩個流的随機數的配置設定情況。預期的結果是:double類型的僞随機數是均勻的配置設定的,而double類型的高斯僞随機數應該是正态分布的。 通過下面的代碼,我生成了一百萬個僞随機數,這是通過java8提供的api實作的:
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 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
為了類比,我們再生成一百萬個高斯僞随機數:
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));
代碼的結果如下:
-1 37252
-0.9 40715
-0.8 43781
-0.7 47587
-0.6 50844
-0.5 52734
-0.4 54704
-0.3 56536
-0.2 58195
-0.1 58493
0 58314
0.1 57346
0.2 56615
0.3 54456
0.4 53111
0.5 50212
0.6 47023
0.7 44338
0.8 40493
0.9 37251
上面代碼輸出的結果恰恰與我們預期結果相吻合,即:double類型的僞随機數是均勻的配置設定的,而double類型的高斯僞随機數應該是正态分布的。
用僞随機數所得的結果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyNzkDNygDNwIjMyIDM0EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
用高斯僞随機數所得的結果:
完整代碼可以在 這裡下載下傳 擷取(隻需要安裝jdk8即可,如果需要jkd8安裝檔案,回複此文章聯系我即可),也可通過如下位址下載下傳 https://gist.github.com/bijukunjummen/8129250
原文連結:http://www.javacodegeeks.com/2014/01/java-util-random-in-java-8.html