天天看點

Java8中的java.util.Random類

     在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類型的高斯僞随機數應該是正态分布的。

用僞随機數所得的結果:

Java8中的java.util.Random類

用高斯僞随機數所得的結果:

Java8中的java.util.Random類

完整代碼可以在 這裡下載下傳 擷取(隻需要安裝jdk8即可,如果需要jkd8安裝檔案,回複此文章聯系我即可),也可通過如下位址下載下傳 https://gist.github.com/bijukunjummen/8129250

原文連結:http://www.javacodegeeks.com/2014/01/java-util-random-in-java-8.html