src/java.base/share/classes/java/util/random/RandomGenerator.java
branchJDK-8193209-branch
changeset 59088 da026c172c1e
equal deleted inserted replaced
59087:effb66aab08b 59088:da026c172c1e
       
     1 /*
       
     2  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package java.util.random;
       
    27 
       
    28 import java.math.BigInteger;
       
    29 import java.util.Objects;
       
    30 import java.util.stream.DoubleStream;
       
    31 import java.util.stream.IntStream;
       
    32 import java.util.stream.LongStream;
       
    33 import java.util.stream.Stream;
       
    34 
       
    35 /**
       
    36  * The {@link RandomGenerator} interface is designed to provide a common protocol for objects that
       
    37  * generate random or (more typically) pseudorandom sequences of numbers (or Boolean values).
       
    38  * Such a sequence may be obtained by either repeatedly invoking a method that returns a single
       
    39  * (pseudo)randomly chosen value, or by invoking a method that returns a stream of (pseudo)randomly
       
    40  * chosen values.
       
    41  * <p>
       
    42  * Ideally, given an implicitly or explicitly specified range of values, each value would be chosen
       
    43  * independently and uniformly from that range. In practice, one may have to settle for some
       
    44  * approximation to independence and uniformity.
       
    45  * <p>
       
    46  * In the case of {@code int}, {@code long}, and {@link Boolean} values, if there is no explicit
       
    47  * specification of range, then the range includes all possible values of the type.  In the case of
       
    48  * {@code float} and {@code double} values, a value is always chosen from the set of
       
    49  * 2<sup><i>w</i></sup> values between 0.0 (inclusive) and 1.0 (exclusive), where <i>w</i> is 23 for
       
    50  * {@code float} values and 52 for {@code double} values, such that adjacent values differ by
       
    51  * 2<sup>&minus;<i>w</i></sup>; if an explicit range is specified, then the chosen number is
       
    52  * computationally scaled and translated so as to appear to have been chosen from that range.
       
    53  * <p>
       
    54  * Each method that returns a stream produces a stream of values each of which is chosen in the same
       
    55  * manner as for a method that returns a single (pseudo)randomly chosen value.  For example, if
       
    56  * {@code r} implements {@link RandomGenerator}, then the method call {@code r.ints(100)} returns a
       
    57  * stream of 100 {@code int} values.  These are not necessarily the exact same values that would
       
    58  * have been returned if instead {@code r.nextInt()} had been called 100 times; all that is
       
    59  * guaranteed is that each value in the stream is chosen in a similar (pseudo)random manner from the
       
    60  * same range.
       
    61  * <p>
       
    62  * Every object that implements the {@link RandomNumberGenerator} interface by using a
       
    63  * pseudorandom algorithm is assumed to contain a finite amount of state.  Using such an object to
       
    64  * generate a pseudorandomly chosen value alters its state by computing a new state as a function
       
    65  * of the current state, without reference to any information other than the current state.
       
    66  * The number of distinct possible states of such an object is called its <i>period</i>.
       
    67  * (Some implementations of the {@link RandomNumberGenerator} interface may be truly random
       
    68  * rather than pseudorandom, for example relying on the statistical behavior of a physical
       
    69  * object to derive chosen values.  Such implementations do not have a fixed period.)
       
    70  * <p>
       
    71  * As a rule, objects that implement the {@link RandomGenerator} interface need not be thread-safe.
       
    72  * It is recommended that multithreaded applications use either {@link ThreadLocalRandom} or
       
    73  * (preferably) pseudorandom number generators that implement the {@link SplittableGenerator} or
       
    74  * {@link JumpableGenerator} interface.
       
    75  * <p>
       
    76  * To implement this interface, a class only needs to provide concrete definitions for the methods
       
    77  * {@code nextLong()} and {@code period()}. Default implementations are provided for all other
       
    78  * methods (but it may be desirable to override some of them, especially {@code nextInt()} if the
       
    79  * underlying algorithm is {@code int}-based). Moreover, it may be preferable instead to implement
       
    80  * a more specialized interface such as {@link JumpableGenerator} or {@link LeapableGenerator},
       
    81  * or to extend an abstract implementation-support class such as {@link AbstractSplittableGenerator}
       
    82  * or {@link AbstractArbitrarilyJumpableGenerator}.
       
    83  * <p>
       
    84  * Objects that implement {@link RandomGenerator} are typically not cryptographically secure.
       
    85  * Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
       
    86  * pseudorandom number generator for use by security-sensitive applications.  Note, however, that
       
    87  * {@code java.security.SecureRandom} does implement the {@link RandomGenerator} interface, so that
       
    88  * instances of {@code java.security.SecureRandom} may be used interchangeably with other types of
       
    89  * pseudorandom generators in applications that do not require a secure generator.
       
    90  *
       
    91  * @since 14
       
    92  */
       
    93 public interface RandomGenerator {
       
    94 
       
    95     /**
       
    96      * Supported random number Algorithms.
       
    97      */
       
    98     public enum Algorithm {
       
    99         /**
       
   100          * L64X128MixRandom algorithm
       
   101          */
       
   102         L64X128MixRandom("L64X128MixRandom"),
       
   103         /**
       
   104          * L64X256MixRandom algorithm
       
   105          */
       
   106         L64X256MixRandom("L64X256MixRandom"),
       
   107         /**
       
   108          * L64X1024MixRandom algorithm
       
   109          */
       
   110         L64X1024MixRandom("L64X1024MixRandom"),
       
   111         /**
       
   112          * L128X256MixRandom algorithm
       
   113          */
       
   114         L128X256MixRandom("L128X256MixRandom"),
       
   115         /**
       
   116          * MRG32k3a algorithm
       
   117          */
       
   118         MRG32k3a("MRG32k3a"),
       
   119         /**
       
   120          * Legacy Random algorithm
       
   121          */
       
   122         @Deprecated
       
   123         Random("Random"),
       
   124         /**
       
   125          * Legacy SecureRandom algorithm
       
   126          */
       
   127         @Deprecated
       
   128         SecureRandom("SecureRandom"),
       
   129         /**
       
   130          * Xoroshiro128StarStar algorithm
       
   131          */
       
   132         Xoroshiro128StarStar("Xoroshiro128StarStar"),
       
   133         /**
       
   134          * Xoshiro256StarStar algorithm
       
   135          */
       
   136         Xoshiro256StarStar("Xoshiro256StarStar");
       
   137 
       
   138         private String name;
       
   139 
       
   140         private Algorithm(String name) {
       
   141             this.name = name;
       
   142         }
       
   143 
       
   144         public String toString() {
       
   145             return name;
       
   146         }
       
   147 
       
   148         /**
       
   149          * Returns an instance of {@link RandomGenerator} that utilizes this algorithm.
       
   150          *
       
   151          * @return An instance of {@link RandomGenerator}
       
   152          */
       
   153         public RandomGenerator instance() {
       
   154             return RandomGeneratorFactory.of(name, RandomGenerator.class);
       
   155         }
       
   156 
       
   157         /**
       
   158          * Returns a {@link RandomGeneratorFactory} that can produce instances
       
   159          * of {@link RandomGenerator} that utilizes this algorithm.
       
   160          *
       
   161          * @return {@link RandomGeneratorFactory} of {@link RandomGenerator}
       
   162          */
       
   163         public RandomGeneratorFactory<RandomGenerator> factory() {
       
   164             return RandomGeneratorFactory.factoryOf(name, RandomGenerator.class);
       
   165         }
       
   166     }
       
   167 
       
   168     /**
       
   169      * Returns an instance of {@link RandomGenerator} that utilizes the
       
   170      * {@code name} algorithm.
       
   171      *
       
   172      * @param name  Name of random number generator algorithm
       
   173      *
       
   174      * @return An instance of {@link RandomGenerator}
       
   175      */
       
   176     public static RandomGenerator of(String name) {
       
   177         Objects.requireNonNull(name);
       
   178         return RandomGeneratorFactory.of(name, RandomGenerator.class);
       
   179     }
       
   180 
       
   181     /**
       
   182      * Returns an instance of {@link RandomGenerator} that utilizes the
       
   183      * specified {@code algorithm}.
       
   184      *
       
   185      * @param algorithm  Random number generator algorithm
       
   186      *
       
   187      * @return An instance of {@link RandomGenerator}
       
   188      */
       
   189     public static RandomGenerator of(Algorithm algorithm) {
       
   190         Objects.requireNonNull(algorithm);
       
   191         return RandomGeneratorFactory.of(algorithm.toString(), RandomGenerator.class);
       
   192     }
       
   193 
       
   194     /**
       
   195      * Returns a {@link RandomGeneratorFactory} that can produce instances
       
   196      * of {@link RandomGenerator} that utilizes the {@code name} algorithm.
       
   197      *
       
   198      * @param name  Name of random number generator algorithm
       
   199      *
       
   200      * @return {@link RandomGeneratorFactory} of {@link RandomGenerator}
       
   201      */
       
   202     public static RandomGeneratorFactory<RandomGenerator> factoryOf(String name) {
       
   203         Objects.requireNonNull(name);
       
   204         return RandomGeneratorFactory.factoryOf(name, RandomGenerator.class);
       
   205     }
       
   206 
       
   207     /**
       
   208      * Returns a {@link RandomGeneratorFactory} that can produce instances
       
   209      * of {@link RandomGenerator} that utilizes the specified {@code algorithm}.
       
   210      *
       
   211      * @param algorithm  Random number generator algorithm
       
   212      *
       
   213      * @return {@link RandomGeneratorFactory} of {@link RandomGenerator}
       
   214      */
       
   215     public static RandomGeneratorFactory<RandomGenerator> factoryOf(Algorithm algorithm) {
       
   216         Objects.requireNonNull(algorithm);
       
   217         return RandomGeneratorFactory.factoryOf(algorithm.toString(), RandomGenerator.class);
       
   218     }
       
   219 
       
   220     /**
       
   221      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   222      * {@code double} values.
       
   223      *
       
   224      * @return a stream of pseudorandomly chosen {@code double} values
       
   225      *
       
   226      * @implNote It is permitted to implement this method in a manner
       
   227      * equivalent to {@code doubles(Long.MAX_VALUE)}.
       
   228      *
       
   229      * @implNote The default implementation produces a sequential stream
       
   230      *           that repeatedly calls {@code nextDouble()}.
       
   231      */
       
   232     default DoubleStream doubles() {
       
   233         return DoubleStream.generate(this::nextDouble).sequential();
       
   234     }
       
   235 
       
   236     /**
       
   237      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   238      * {@code double} values, where each value is between the specified
       
   239      * origin (inclusive) and the specified bound (exclusive).
       
   240      *
       
   241      * @param randomNumberOrigin the least value that can be produced
       
   242      * @param randomNumberBound the upper bound (exclusive) for each value produced
       
   243      *
       
   244      * @return a stream of pseudorandomly chosen {@code double} values, each between
       
   245      *         the specified origin (inclusive) and the specified bound (exclusive)
       
   246      *
       
   247      * @throws IllegalArgumentException if {@code randomNumberOrigin} is not finite,
       
   248      *         or {@code randomNumberBound} is not finite, or {@code randomNumberOrigin}
       
   249      *         is greater than or equal to {@code randomNumberBound}
       
   250      *
       
   251      * @implNote It is permitted to implement this method in a manner equivalent to
       
   252      *           {@code doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
       
   253      * @implNote The default implementation produces a sequential stream that repeatedly
       
   254      *           calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}.
       
   255      */
       
   256     default DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
       
   257         RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   258         return DoubleStream.generate(() -> nextDouble(randomNumberOrigin, randomNumberBound)).sequential();
       
   259     }
       
   260 
       
   261     /**
       
   262      * Returns a stream producing the given {@code streamSize} number of
       
   263      * pseudorandomly chosen {@code double} values.
       
   264      *
       
   265      * @param streamSize the number of values to generate
       
   266      *
       
   267      * @return a stream of pseudorandomly chosen {@code double} values
       
   268      *
       
   269      * @throws IllegalArgumentException if {@code streamSize} is
       
   270      *         less than zero
       
   271      *
       
   272      * @implNote The default implementation produces a sequential stream
       
   273      * that repeatedly calls {@code nextDouble()}.
       
   274      */
       
   275     default DoubleStream doubles(long streamSize) {
       
   276         RandomSupport.checkStreamSize(streamSize);
       
   277         return doubles().limit(streamSize);
       
   278     }
       
   279 
       
   280     /**
       
   281      * Returns a stream producing the given {@code streamSize} number of
       
   282      * pseudorandomly chosen {@code double} values, where each value is between
       
   283      * the specified origin (inclusive) and the specified bound (exclusive).
       
   284      *
       
   285      * @param streamSize the number of values to generate
       
   286      * @param randomNumberOrigin the least value that can be produced
       
   287      * @param randomNumberBound the upper bound (exclusive) for each value produced
       
   288      *
       
   289      * @return a stream of pseudorandomly chosen {@code double} values, each between
       
   290      *         the specified origin (inclusive) and the specified bound (exclusive)
       
   291      *
       
   292      * @throws IllegalArgumentException if {@code streamSize} is less than zero,
       
   293      *         or {@code randomNumberOrigin} is not finite,
       
   294      *         or {@code randomNumberBound} is not finite, or {@code randomNumberOrigin}
       
   295      *         is greater than or equal to {@code randomNumberBound}
       
   296      *
       
   297      * @implNote The default implementation produces a sequential stream that repeatedly
       
   298      *           calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}.
       
   299      */
       
   300     default DoubleStream doubles(long streamSize, double randomNumberOrigin,
       
   301 				 double randomNumberBound) {
       
   302         RandomSupport.checkStreamSize(streamSize);
       
   303         RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   304         return doubles(randomNumberOrigin, randomNumberBound).limit(streamSize);
       
   305     }
       
   306 
       
   307     /**
       
   308      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   309      * {@code int} values.
       
   310      *
       
   311      * @return a stream of pseudorandomly chosen {@code int} values
       
   312      *
       
   313      * @implNote It is permitted to implement this method in a manner
       
   314      *           equivalent to {@code ints(Long.MAX_VALUE)}.
       
   315      * @implNote The default implementation produces a sequential stream
       
   316      *           that repeatedly calls {@code nextInt()}.
       
   317      */
       
   318     default IntStream ints() {
       
   319         return IntStream.generate(this::nextInt).sequential();
       
   320     }
       
   321 
       
   322     /**
       
   323      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   324      * {@code int} values, where each value is between the specified
       
   325      * origin (inclusive) and the specified bound (exclusive).
       
   326      *
       
   327      * @param randomNumberOrigin the least value that can be produced
       
   328      * @param randomNumberBound the upper bound (exclusive) for each value produced
       
   329      *
       
   330      * @return a stream of pseudorandomly chosen {@code int} values, each between
       
   331      *         the specified origin (inclusive) and the specified bound (exclusive)
       
   332      *
       
   333      * @throws IllegalArgumentException if {@code randomNumberOrigin}
       
   334      *         is greater than or equal to {@code randomNumberBound}
       
   335      *
       
   336      * @implNote It is permitted to implement this method in a manner equivalent to
       
   337      *           {@code ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
       
   338      * @implNote The default implementation produces a sequential stream that repeatedly
       
   339      *           calls {@code nextInt(randomNumberOrigin, randomNumberBound)}.
       
   340      */
       
   341     default IntStream ints(int randomNumberOrigin, int randomNumberBound) {
       
   342         RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   343         return IntStream.generate(() -> nextInt(randomNumberOrigin, randomNumberBound)).sequential();
       
   344     }
       
   345 
       
   346     /**
       
   347      * Returns a stream producing the given {@code streamSize} number of
       
   348      * pseudorandomly chosen {@code int} values.
       
   349      *
       
   350      * @param streamSize the number of values to generate
       
   351      *
       
   352      * @return a stream of pseudorandomly chosen {@code int} values
       
   353      *
       
   354      * @throws IllegalArgumentException if {@code streamSize} is
       
   355      *         less than zero
       
   356      *
       
   357      * @implNote The default implementation produces a sequential stream
       
   358      *           that repeatedly calls {@code nextInt()}.
       
   359      */
       
   360     default IntStream ints(long streamSize) {
       
   361         RandomSupport.checkStreamSize(streamSize);
       
   362         return ints().limit(streamSize);
       
   363     }
       
   364 
       
   365     /**
       
   366      * Returns a stream producing the given {@code streamSize} number of
       
   367      * pseudorandomly chosen {@code int} values, where each value is between
       
   368      * the specified origin (inclusive) and the specified bound (exclusive).
       
   369      *
       
   370      * @param streamSize the number of values to generate
       
   371      * @param randomNumberOrigin the least value that can be produced
       
   372      * @param randomNumberBound the upper bound (exclusive) for each value produced
       
   373      *
       
   374      * @return a stream of pseudorandomly chosen {@code int} values, each between
       
   375      *         the specified origin (inclusive) and the specified bound (exclusive)
       
   376      *
       
   377      * @throws IllegalArgumentException if {@code streamSize} is
       
   378      *         less than zero, or {@code randomNumberOrigin}
       
   379      *         is greater than or equal to {@code randomNumberBound}
       
   380      *
       
   381      * @implNote The default implementation produces a sequential stream that repeatedly
       
   382      *           calls {@code nextInt(randomNumberOrigin, randomNumberBound)}.
       
   383      */
       
   384     default IntStream ints(long streamSize, int randomNumberOrigin,
       
   385 			   int randomNumberBound) {
       
   386         RandomSupport.checkStreamSize(streamSize);
       
   387         RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   388         return ints(randomNumberOrigin, randomNumberBound).limit(streamSize);
       
   389     }
       
   390 
       
   391     /**
       
   392      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   393      * {@code long} values.
       
   394      *
       
   395      * @return a stream of pseudorandomly chosen {@code long} values
       
   396      *
       
   397      * @implNote It is permitted to implement this method in a manner
       
   398      *           equivalent to {@code longs(Long.MAX_VALUE)}.
       
   399      * @implNote The default implementation produces a sequential stream
       
   400      *           that repeatedly calls {@code nextLong()}.
       
   401      */
       
   402     default LongStream longs() {
       
   403         return LongStream.generate(this::nextLong).sequential();
       
   404     }
       
   405 
       
   406     /**
       
   407      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   408      * {@code long} values, where each value is between the specified
       
   409      * origin (inclusive) and the specified bound (exclusive).
       
   410      *
       
   411      * @param randomNumberOrigin the least value that can be produced
       
   412      * @param randomNumberBound the upper bound (exclusive) for each value produced
       
   413      *
       
   414      * @return a stream of pseudorandomly chosen {@code long} values, each between
       
   415      *         the specified origin (inclusive) and the specified bound (exclusive)
       
   416      *
       
   417      * @throws IllegalArgumentException if {@code randomNumberOrigin}
       
   418      *         is greater than or equal to {@code randomNumberBound}
       
   419      *
       
   420      * @implNote It is permitted to implement this method in a manner equivalent to
       
   421      *           {@code longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
       
   422      * @implNote The default implementation produces a sequential stream that repeatedly
       
   423      *           calls {@code nextLong(randomNumberOrigin, randomNumberBound)}.
       
   424      */
       
   425     default LongStream longs(long randomNumberOrigin, long randomNumberBound) {
       
   426         RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   427         return LongStream.generate(() -> nextLong(randomNumberOrigin, randomNumberBound)).sequential();
       
   428     }
       
   429 
       
   430     /**
       
   431      * Returns a stream producing the given {@code streamSize} number of
       
   432      * pseudorandomly chosen {@code long} values.
       
   433      *
       
   434      * @param streamSize the number of values to generate
       
   435      *
       
   436      * @return a stream of pseudorandomly chosen {@code long} values
       
   437      *
       
   438      * @throws IllegalArgumentException if {@code streamSize} is
       
   439      *         less than zero
       
   440      *
       
   441      * @implNote The default implementation produces a sequential stream
       
   442      * that repeatedly calls {@code nextLong()}.
       
   443      */
       
   444     default LongStream longs(long streamSize) {
       
   445         RandomSupport.checkStreamSize(streamSize);
       
   446         return longs().limit(streamSize);
       
   447     }
       
   448 
       
   449     /**
       
   450      * Returns a stream producing the given {@code streamSize} number of
       
   451      * pseudorandomly chosen {@code long} values, where each value is between
       
   452      * the specified origin (inclusive) and the specified bound (exclusive).
       
   453      *
       
   454      * @param streamSize the number of values to generate
       
   455      * @param randomNumberOrigin the least value that can be produced
       
   456      * @param randomNumberBound the upper bound (exclusive) for each value produced
       
   457      *
       
   458      * @return a stream of pseudorandomly chosen {@code long} values, each between
       
   459      *         the specified origin (inclusive) and the specified bound (exclusive)
       
   460      *
       
   461      * @throws IllegalArgumentException if {@code streamSize} is
       
   462      *         less than zero, or {@code randomNumberOrigin}
       
   463      *         is greater than or equal to {@code randomNumberBound}
       
   464      *
       
   465      * @implNote The default implementation produces a sequential stream that repeatedly
       
   466      *            calls {@code nextLong(randomNumberOrigin, randomNumberBound)}.
       
   467      */
       
   468     default LongStream longs(long streamSize, long randomNumberOrigin,
       
   469 			     long randomNumberBound) {
       
   470         RandomSupport.checkStreamSize(streamSize);
       
   471         RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   472         return longs(randomNumberOrigin, randomNumberBound).limit(streamSize);
       
   473     }
       
   474 
       
   475     /**
       
   476      * Returns a pseudorandomly chosen {@code boolean} value.
       
   477      * <p>
       
   478      * The default implementation tests the high-order bit (sign bit) of a value produced by
       
   479      * {@code nextInt()}, on the grounds that some algorithms for pseudorandom number generation
       
   480      * produce values whose high-order bits have better statistical quality than the low-order bits.
       
   481      *
       
   482      * @return a pseudorandomly chosen {@code boolean} value
       
   483      */
       
   484     default boolean nextBoolean() {
       
   485         return nextInt() < 0;
       
   486     }
       
   487 
       
   488     /**
       
   489      * Returns a pseudorandom {@code float} value between zero (inclusive) and one (exclusive).
       
   490      * <p>
       
   491      * The default implementation uses the 24 high-order bits from a call to {@code nextInt()}.
       
   492      *
       
   493      * @return a pseudorandom {@code float} value between zero (inclusive) and one (exclusive)
       
   494      */
       
   495     default float nextFloat() {
       
   496         return (nextInt() >>> 8) * 0x1.0p-24f;
       
   497     }
       
   498 
       
   499     /**
       
   500      * Returns a pseudorandomly chosen {@code float} value between zero
       
   501      * (inclusive) and the specified bound (exclusive).
       
   502      *
       
   503      * @param bound the upper bound (exclusive) for the returned value.
       
   504      *        Must be positive and finite
       
   505      *
       
   506      * @return a pseudorandomly chosen {@code float} value between
       
   507      *         zero (inclusive) and the bound (exclusive)
       
   508      *
       
   509      * @throws IllegalArgumentException if {@code bound} is not
       
   510      *         both positive and finite
       
   511      *
       
   512      * @implNote The default implementation simply calls
       
   513      *           {@code RandomSupport.checkBound(bound)} and then
       
   514      *           {@code RandomSupport.boundedNextFloat(this, bound)}.
       
   515      */
       
   516     default float nextFloat(float bound) {
       
   517         RandomSupport.checkBound(bound);
       
   518         return RandomSupport.boundedNextFloat(this, bound);
       
   519     }
       
   520 
       
   521     /**
       
   522      * Returns a pseudorandomly chosen {@code float} value between the
       
   523      * specified origin (inclusive) and the specified bound (exclusive).
       
   524      *
       
   525      * @param origin the least value that can be returned
       
   526      * @param bound the upper bound (exclusive)
       
   527      *
       
   528      * @return a pseudorandomly chosen {@code float} value between the
       
   529      *         origin (inclusive) and the bound (exclusive)
       
   530      *
       
   531      * @throws IllegalArgumentException if {@code origin} is not finite,
       
   532      *         or {@code bound} is not finite, or {@code origin}
       
   533      *         is greater than or equal to {@code bound}
       
   534      *
       
   535      * @implNote The default implementation simply calls
       
   536      *           {@code RandomSupport.checkRange(origin, bound)} and then
       
   537      *           {@code RandomSupport.boundedNextFloat(this, origin, bound)}.
       
   538      */
       
   539     default float nextFloat(float origin, float bound) {
       
   540         RandomSupport.checkRange(origin, bound);
       
   541         return RandomSupport.boundedNextFloat(this, origin, bound);
       
   542     }
       
   543 
       
   544     /**
       
   545      * Returns a pseudorandom {@code double} value between zero (inclusive) and one (exclusive).
       
   546      * <p>
       
   547      * The default implementation uses the 53 high-order bits from a call to {@code nextLong()}.
       
   548      *
       
   549      * @return a pseudorandom {@code double} value between zero (inclusive) and one (exclusive)
       
   550      */
       
   551     default double nextDouble() {
       
   552         return (nextLong() >>> 11) * 0x1.0p-53;
       
   553     }
       
   554 
       
   555     /**
       
   556      * Returns a pseudorandomly chosen {@code double} value between zero
       
   557      * (inclusive) and the specified bound (exclusive).
       
   558      *
       
   559      * @param bound the upper bound (exclusive) for the returned value.
       
   560      *        Must be positive and finite
       
   561      *
       
   562      * @return a pseudorandomly chosen {@code double} value between
       
   563      *         zero (inclusive) and the bound (exclusive)
       
   564      *
       
   565      * @throws IllegalArgumentException if {@code bound} is not
       
   566      *         both positive and finite
       
   567      *
       
   568      * @implNote The default implementation simply calls
       
   569      *           {@code RandomSupport.checkBound(bound)} and then
       
   570      *           {@code RandomSupport.boundedNextDouble(this, bound)}.
       
   571      */
       
   572     default double nextDouble(double bound) {
       
   573         RandomSupport.checkBound(bound);
       
   574         return RandomSupport.boundedNextDouble(this, bound);
       
   575     }
       
   576 
       
   577     /**
       
   578      * Returns a pseudorandomly chosen {@code double} value between the
       
   579      * specified origin (inclusive) and the specified bound (exclusive).
       
   580      *
       
   581      * @param origin the least value that can be returned
       
   582      * @param bound the upper bound (exclusive) for the returned value
       
   583      *
       
   584      * @return a pseudorandomly chosen {@code double} value between the
       
   585      *         origin (inclusive) and the bound (exclusive)
       
   586      *
       
   587      * @throws IllegalArgumentException if {@code origin} is not finite,
       
   588      *         or {@code bound} is not finite, or {@code origin}
       
   589      *         is greater than or equal to {@code bound}
       
   590      *
       
   591      * @implNote The default implementation simply calls
       
   592      *           {@code RandomSupport.checkRange(origin, bound)} and then
       
   593      *           {@code RandomSupport.boundedNextDouble(this, origin, bound)}.
       
   594      */
       
   595     default double nextDouble(double origin, double bound) {
       
   596         RandomSupport.checkRange(origin, bound);
       
   597         return RandomSupport.boundedNextDouble(this, origin, bound);
       
   598     }
       
   599 
       
   600     /**
       
   601      * Returns a pseudorandomly chosen {@code int} value.
       
   602      * <p>
       
   603      * The default implementation uses the 32 high-order bits from a call to {@code nextLong()}.
       
   604      *
       
   605      * @return a pseudorandomly chosen {@code int} value
       
   606      */
       
   607     default public int nextInt() {
       
   608         return (int)(nextLong() >>> 32);
       
   609     }
       
   610 
       
   611     /**
       
   612      * Returns a pseudorandomly chosen {@code int} value between
       
   613      * zero (inclusive) and the specified bound (exclusive).
       
   614      *
       
   615      * @param bound the upper bound (exclusive) for the returned value. Must be positive.
       
   616      *
       
   617      * @return a pseudorandomly chosen {@code int} value between
       
   618      *         zero (inclusive) and the bound (exclusive)
       
   619      *
       
   620      * @throws IllegalArgumentException if {@code bound} is not positive
       
   621      *
       
   622      * @implNote The default implementation simply calls
       
   623      *           {@code RandomSupport.checkBound(bound)} and then
       
   624      *           {@code RandomSupport.boundedNextInt(this, bound)}.
       
   625      */
       
   626     default int nextInt(int bound) {
       
   627         RandomSupport.checkBound(bound);
       
   628         return RandomSupport.boundedNextInt(this, bound);
       
   629     }
       
   630 
       
   631     /**
       
   632      * Returns a pseudorandomly chosen {@code int} value between the
       
   633      * specified origin (inclusive) and the specified bound (exclusive).
       
   634      *
       
   635      * @param origin the least value that can be returned
       
   636      * @param bound the upper bound (exclusive) for the returned value
       
   637      *
       
   638      * @return a pseudorandomly chosen {@code int} value between the
       
   639      *         origin (inclusive) and the bound (exclusive)
       
   640      *
       
   641      * @throws IllegalArgumentException if {@code origin} is greater than
       
   642      *         or equal to {@code bound}
       
   643      *
       
   644      * @implNote The default implementation simply calls
       
   645      *           {@code RandomSupport.checkRange(origin, bound)} and then
       
   646      *           {@code RandomSupport.boundedNextInt(this, origin, bound)}.
       
   647      */
       
   648     default int nextInt(int origin, int bound) {
       
   649         RandomSupport.checkRange(origin, bound);
       
   650         return RandomSupport.boundedNextInt(this, origin, bound);
       
   651     }
       
   652 
       
   653     /**
       
   654      * Returns a pseudorandomly chosen {@code long} value.
       
   655      *
       
   656      * @return a pseudorandomly chosen {@code long} value
       
   657      */
       
   658     long nextLong();
       
   659 
       
   660     /**
       
   661      * Returns a pseudorandomly chosen {@code long} value between
       
   662      * zero (inclusive) and the specified bound (exclusive).
       
   663      *
       
   664      * @param bound the upper bound (exclusive) for the returned value.  Must be positive.
       
   665      *
       
   666      * @return a pseudorandomly chosen {@code long} value between
       
   667      *         zero (inclusive) and the bound (exclusive)
       
   668      *
       
   669      * @throws IllegalArgumentException if {@code bound} is not positive
       
   670      *
       
   671      * @implNote The default implementation simply calls
       
   672      *           {@code RandomSupport.checkBound(bound)} and then
       
   673      *           {@code RandomSupport.boundedNextLong(this, bound)}.
       
   674      */
       
   675     default long nextLong(long bound) {
       
   676         RandomSupport.checkBound(bound);
       
   677         return RandomSupport.boundedNextLong(this, bound);
       
   678     }
       
   679 
       
   680     /**
       
   681      * Returns a pseudorandomly chosen {@code long} value between the
       
   682      * specified origin (inclusive) and the specified bound (exclusive).
       
   683      *
       
   684      * @param origin the least value that can be returned
       
   685      * @param bound the upper bound (exclusive) for the returned value
       
   686      *
       
   687      * @return a pseudorandomly chosen {@code long} value between the
       
   688      *         origin (inclusive) and the bound (exclusive)
       
   689      *
       
   690      * @throws IllegalArgumentException if {@code origin} is greater than
       
   691      *         or equal to {@code bound}
       
   692      *
       
   693      * @implNote The default implementation simply calls
       
   694      *           {@code RandomSupport.checkRange(origin, bound)} and then
       
   695      *           {@code RandomSupport.boundedNextInt(this, origin, bound)}.
       
   696      *
       
   697      */
       
   698     default long nextLong(long origin, long bound) {
       
   699         RandomSupport.checkRange(origin, bound);
       
   700         return RandomSupport.boundedNextLong(this, origin, bound);
       
   701     }
       
   702 
       
   703     /**
       
   704      * Returns a {@code double} value pseudorandomly chosen from
       
   705      * a Gaussian (normal) distribution whose mean is 0 and whose
       
   706      * standard deviation is 1.
       
   707      *
       
   708      * @return a {@code double} value pseudorandomly chosen from a
       
   709      *         Gaussian distribution
       
   710      */
       
   711     default double nextGaussian() {
       
   712         return RandomSupport.computeNextGaussian(this);
       
   713     }
       
   714 
       
   715     /**
       
   716      * Returns a {@code double} value pseudorandomly chosen from
       
   717      * a Gaussian (normal) distribution with a mean and
       
   718      * standard deviation specified by the arguments.
       
   719      *
       
   720      * @param mean the mean of the Gaussian distribution to be drawn from
       
   721      * @param stddev the standard deviation (square root of the variance)
       
   722      *        of the Gaussian distribution to be drawn from
       
   723      *
       
   724      * @return a {@code double} value pseudorandomly chosen from the
       
   725      *         specified Gaussian distribution
       
   726      *
       
   727      * @throws IllegalArgumentException if {@code stddev} is negative
       
   728      */
       
   729     default double nextGaussian(double mean, double stddev) {
       
   730         if (stddev < 0.0) throw new IllegalArgumentException("standard deviation must be non-negative");
       
   731         return mean + stddev * RandomSupport.computeNextGaussian(this);
       
   732     }
       
   733 
       
   734     /**
       
   735      * Returns a nonnegative {@code double} value pseudorandomly chosen
       
   736      * from an exponential distribution whose mean is 1.
       
   737      *
       
   738      * @return a nonnegative {@code double} value pseudorandomly chosen from an
       
   739      *         exponential distribution
       
   740      */
       
   741     default double nextExponential() {
       
   742         return RandomSupport.computeNextExponential(this);
       
   743     }
       
   744 
       
   745     /**
       
   746      * Returns the period of this {@link RandomGenerator} object.
       
   747      *
       
   748      * @return a {@link BigInteger} whose value is the number of distinct possible states of this
       
   749      *         {@link RandomGenerator} object, or 0 if unknown, or negative if extremely
       
   750      *         large.
       
   751      */
       
   752     BigInteger period();
       
   753 
       
   754     /**
       
   755      * The value (0) returned by the {@code period()} method if the period is unknown.
       
   756      */
       
   757     static final BigInteger UNKNOWN_PERIOD = BigInteger.ZERO;
       
   758 
       
   759     /**
       
   760      * The (negative) value returned by the {@code period()} method if this generator
       
   761      * has no period because it is truly random rather than just pseudorandom.
       
   762      */
       
   763     static final BigInteger TRULY_RANDOM = BigInteger.valueOf(-1);
       
   764 
       
   765     /**
       
   766      * The (negative) value that may be returned by the {@code period()} method
       
   767      * if this generator has a huge period (larger than 2**(2**16)).
       
   768      */
       
   769     static final BigInteger HUGE_PERIOD = BigInteger.valueOf(-2);
       
   770 
       
   771     /**
       
   772      * The {@link StreamableGenerator} interface augments the {@link RandomGenerator} interface
       
   773      * to provide methods that return streams of {@link RandomGenerator} objects.
       
   774      * Ideally, such a stream of objects would have the property that the
       
   775      * behavior of each object is statistically independent of all the others.
       
   776      * In practice, one may have to settle for some approximation to this property.
       
   777      *
       
   778      * A generator that implements interface {@link SplittableGenerator}
       
   779      * may choose to use its {@code splits} method to implement the {@code rngs}
       
   780      * method required by this interface.
       
   781      *
       
   782      * A generator that implements interface {@link JumpableGenerator}
       
   783      * may choose to use its {@code jumps} method to implement the {@code rngs}
       
   784      * method required by this interface.
       
   785      *
       
   786      * A generator that implements interface {@link LeapableGenerator}
       
   787      * may choose to use its {@code leaps} method to implement the {@code rngs}
       
   788      * method required by this interface.
       
   789      * <p>
       
   790      * An implementation of the {@link StreamableGenerator} interface must provide
       
   791      * concrete definitions for the methods {@code nextInt()}, {@code nextLong},
       
   792      * {@code period()}, and {@code rngs()}.
       
   793      * Default implementations are provided for all other methods.
       
   794      * <p>
       
   795      * Objects that implement {@link StreamableGenerator} are typically
       
   796      * not cryptographically secure.  Consider instead using
       
   797      * {@link java.security.SecureRandom} to get a cryptographically
       
   798      * secure pseudo-random number generator for use by
       
   799      * security-sensitive applications.
       
   800      *
       
   801      * @since 14
       
   802      */
       
   803     public interface StreamableGenerator extends RandomGenerator {
       
   804 
       
   805         /**
       
   806          * Returns an instance of {@link StreamableGenerator} that utilizes the
       
   807          * {@code name} algorithm.
       
   808          *
       
   809          * @param name  Name of random number generator algorithm
       
   810          *
       
   811          * @return An instance of {@link StreamableGenerator}
       
   812          */
       
   813         public static StreamableGenerator of(String name) {
       
   814             Objects.requireNonNull(name);
       
   815             return RandomGeneratorFactory.of(name, StreamableGenerator.class);
       
   816         }
       
   817 
       
   818         /**
       
   819          * Returns an instance of {@link StreamableGenerator} that utilizes the
       
   820          * specified {@code algorithm}.
       
   821          *
       
   822          * @param algorithm  Random number generator algorithm
       
   823          *
       
   824          * @return An instance of {@link StreamableGenerator}
       
   825          */
       
   826         public static StreamableGenerator of(Algorithm algorithm) {
       
   827             Objects.requireNonNull(algorithm);
       
   828             return RandomGeneratorFactory.of(algorithm.toString(), StreamableGenerator.class);
       
   829         }
       
   830 
       
   831         /**
       
   832          * Returns a {@link RandomGeneratorFactory} that can produce instances
       
   833          * of {@link StreamableGenerator} that utilizes the {@code name} algorithm.
       
   834          *
       
   835          * @param name  Name of random number generator algorithm
       
   836          *
       
   837          * @return {@link RandomGeneratorFactory} of {@link StreamableGenerator}
       
   838          */
       
   839         public static RandomGeneratorFactory<StreamableGenerator> factoryOf(String name) {
       
   840             Objects.requireNonNull(name);
       
   841             return RandomGeneratorFactory.factoryOf(name, StreamableGenerator.class);
       
   842         }
       
   843 
       
   844         /**
       
   845          * Returns a {@link RandomGeneratorFactory} that can produce instances
       
   846          * of {@link StreamableGenerator} that utilizes the specified {@code algorithm}.
       
   847          *
       
   848          * @param algorithm  Random number generator algorithm
       
   849          *
       
   850          * @return {@link RandomGeneratorFactory} of {@link StreamableGenerator}
       
   851          */
       
   852         public static RandomGeneratorFactory<StreamableGenerator> factoryOf(Algorithm algorithm) {
       
   853             Objects.requireNonNull(algorithm);
       
   854             return RandomGeneratorFactory.factoryOf(algorithm.toString(), StreamableGenerator.class);
       
   855         }
       
   856 
       
   857         /**
       
   858          * Returns an effectively unlimited stream of objects, each of
       
   859          * which implements the {@link RandomGenerator} interface.  Ideally the
       
   860          * generators in the stream will appear to be statistically
       
   861          * independent.  The new generators should be of the same kind
       
   862          * as this generator.
       
   863          *
       
   864          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
   865          *
       
   866          * @implNote It is permitted to implement this method in a manner
       
   867          *           equivalent to {@code rngs(Long.MAX_VALUE)}.
       
   868          */
       
   869         Stream<RandomGenerator> rngs();
       
   870 
       
   871         /**
       
   872          * Returns an effectively unlimited stream of objects, each of
       
   873          * which implements the {@link RandomGenerator} interface.  Ideally the
       
   874          * generators in the stream will appear to be statistically
       
   875          * independent.  The new generators should be of the same kind
       
   876          * as this generator.
       
   877          *
       
   878          * @param streamSize the number of generators to generate
       
   879          *
       
   880          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
   881          *
       
   882          * @throws IllegalArgumentException if {@code streamSize} is
       
   883          *         less than zero
       
   884          *
       
   885          * @implNote The default implementation calls {@code rngs()} and
       
   886          *           then limits its length to {@code streamSize}.
       
   887          */
       
   888         default Stream<RandomGenerator> rngs(long streamSize) {
       
   889             RandomSupport.checkStreamSize(streamSize);
       
   890             return rngs().limit(streamSize);
       
   891         }
       
   892     }
       
   893 
       
   894     /**
       
   895      * This interface is designed to provide a common protocol for objects
       
   896      * that generate sequences of pseudorandom numbers (or Boolean values)
       
   897      * and furthermore can be <i>split</i> into two objects (the original
       
   898      * one and a new one) each of which obey that same protocol (and therefore
       
   899      * can be recursively split indefinitely).
       
   900      * <p>
       
   901      * Ideally, all {@link SplittableGenerator} objects produced by recursive
       
   902      * splitting from a single original {@link SplittableGenerator} object are
       
   903      * statistically independent of one another and individually uniform.
       
   904      * Therefore we would expect the set of values collectively generated
       
   905      * by a set of such objects to have the same statistical properties as
       
   906      * if the same quantity of values were generated by a single thread
       
   907      * using a single {@link SplittableGenerator} object.  In practice, one must
       
   908      * settle for some approximation to independence and uniformity.
       
   909      * <p>
       
   910      * Methods are provided to perform a single splitting operation and
       
   911      * also to produce a stream of generators split off from the original
       
   912      * (by either iterative or recursive splitting, or a combination).
       
   913      * <p>
       
   914      * An implementation of the {@link SplittableGenerator} interface must provide
       
   915      * concrete definitions for the methods {@code nextInt()}, {@code nextLong},
       
   916      * {@code period()}, {@code split()}, {@code split(SplittableGenerator)},
       
   917      * {@code splits()}, {@code splits(long)}, {@code splits(SplittableGenerator)},
       
   918      * and {@code splits(long, SplittableGenerator)}.  Perhaps the most convenient
       
   919      * way to implement this interface is to extend the abstract class
       
   920      * {@link AbstractSplittableGenerator}.
       
   921      * <p>
       
   922      * Objects that implement {@link SplittableGenerator} are
       
   923      * typically not cryptographically secure.  Consider instead using
       
   924      * {@link java.security.SecureRandom} to get a cryptographically
       
   925      * secure pseudo-random number generator for use by
       
   926      * security-sensitive applications.
       
   927      *
       
   928      * @since 14
       
   929      */
       
   930     public interface SplittableGenerator extends StreamableGenerator {
       
   931 
       
   932         /**
       
   933          * Returns an instance of {@link SplittableGenerator} that utilizes the
       
   934          * {@code name} algorithm.
       
   935          *
       
   936          * @param name  Name of random number generator algorithm
       
   937          *
       
   938          * @return An instance of {@link SplittableGenerator}
       
   939          */
       
   940         public static SplittableGenerator of(String name) {
       
   941             Objects.requireNonNull(name);
       
   942             return RandomGeneratorFactory.of(name, SplittableGenerator.class);
       
   943         }
       
   944 
       
   945         /**
       
   946          * Returns an instance of {@link SplittableGenerator} that utilizes the
       
   947          * specified {@code algorithm}.
       
   948          *
       
   949          * @param algorithm  Random number generator algorithm
       
   950          *
       
   951          * @return An instance of {@link SplittableGenerator}
       
   952          */
       
   953         public static SplittableGenerator of(Algorithm algorithm) {
       
   954             Objects.requireNonNull(algorithm);
       
   955             return RandomGeneratorFactory.of(algorithm.toString(), SplittableGenerator.class);
       
   956         }
       
   957 
       
   958         /**
       
   959          * Returns a {@link RandomGeneratorFactory} that can produce instances
       
   960          * of {@link SplittableGenerator} that utilizes the {@code name} algorithm.
       
   961          *
       
   962          * @param name  Name of random number generator algorithm
       
   963          *
       
   964          * @return {@link RandomGeneratorFactory} of {@link SplittableGenerator}
       
   965          */
       
   966         public static RandomGeneratorFactory<SplittableGenerator> factoryOf(String name) {
       
   967             Objects.requireNonNull(name);
       
   968             return RandomGeneratorFactory.factoryOf(name, SplittableGenerator.class);
       
   969         }
       
   970 
       
   971         /**
       
   972          * Returns a {@link RandomGeneratorFactory} that can produce instances
       
   973          * of {@link SplittableGenerator} that utilizes the specified {@code algorithm}.
       
   974          *
       
   975          * @param algorithm  Random number generator algorithm
       
   976          *
       
   977          * @return {@link RandomGeneratorFactory} of {@link SplittableGenerator}
       
   978          */
       
   979         public static RandomGeneratorFactory<SplittableGenerator> factoryOf(Algorithm algorithm) {
       
   980             Objects.requireNonNull(algorithm);
       
   981             return RandomGeneratorFactory.factoryOf(algorithm.toString(), SplittableGenerator.class);
       
   982         }
       
   983 
       
   984         /**
       
   985          * Returns a new pseudorandom number generator, split off from
       
   986          * this one, that implements the {@link RandomGenerator} and {@link SplittableGenerator}
       
   987          * interfaces.
       
   988          *
       
   989          * This pseudorandom number generator may be used as a source of
       
   990          * pseudorandom bits used to initialize the state the new one.
       
   991          *
       
   992          * @return a new object that implements the {@link RandomGenerator} and
       
   993          *         {@link SplittableGenerator} interfaces
       
   994          */
       
   995         SplittableGenerator split();
       
   996 
       
   997         /**
       
   998          * Returns a new pseudorandom number generator, split off from
       
   999          * this one, that implements the {@link RandomGenerator} and {@link SplittableGenerator}
       
  1000          * interfaces.
       
  1001          *
       
  1002          * @param source a {@link SplittableGenerator} instance to be used instead
       
  1003          *               of this one as a source of pseudorandom bits used to
       
  1004          *               initialize the state of the new ones.
       
  1005          *
       
  1006          * @return an object that implements the {@link RandomGenerator} and
       
  1007          *         {@link SplittableGenerator} interfaces
       
  1008          */
       
  1009         SplittableGenerator split(SplittableGenerator source);
       
  1010 
       
  1011         /**
       
  1012          * Returns an effectively unlimited stream of new pseudorandom
       
  1013          * number generators, each of which implements the {@link SplittableGenerator}
       
  1014          * interface.
       
  1015          *
       
  1016          * This pseudorandom number generator may be used as a source of
       
  1017          * pseudorandom bits used to initialize the state the new ones.
       
  1018          *
       
  1019          * @implNote It is permitted to implement this method in a manner
       
  1020          * equivalent to {@code splits(Long.MAX_VALUE)}.
       
  1021          *
       
  1022          * @return a stream of {@link SplittableGenerator} objects
       
  1023          */
       
  1024         default Stream<SplittableGenerator> splits() {
       
  1025             return this.splits(this);
       
  1026         }
       
  1027 
       
  1028         /**
       
  1029          * Returns a stream producing the given {@code streamSize} number of
       
  1030          * new pseudorandom number generators, each of which implements the
       
  1031          * {@link SplittableGenerator} interface.
       
  1032          *
       
  1033          * This pseudorandom number generator may be used as a source of
       
  1034          * pseudorandom bits used to initialize the state the new ones.
       
  1035          *
       
  1036          * @param streamSize the number of values to generate
       
  1037          *
       
  1038          * @return a stream of {@link SplittableGenerator} objects
       
  1039          *
       
  1040          * @throws IllegalArgumentException if {@code streamSize} is
       
  1041          *         less than zero
       
  1042          */
       
  1043         Stream<SplittableGenerator> splits(long streamSize);
       
  1044 
       
  1045         /**
       
  1046          * Returns an effectively unlimited stream of new pseudorandom
       
  1047          * number generators, each of which implements the {@link SplittableGenerator}
       
  1048          * interface.
       
  1049          *
       
  1050          * @param source a {@link SplittableGenerator} instance to be used instead
       
  1051          *               of this one as a source of pseudorandom bits used to
       
  1052          *               initialize the state of the new ones.
       
  1053          *
       
  1054          * @return a stream of {@link SplittableGenerator} objects
       
  1055          *
       
  1056          * @implNote It is permitted to implement this method in a manner
       
  1057          *           equivalent to {@code splits(Long.MAX_VALUE, source)}.
       
  1058          */
       
  1059         Stream<SplittableGenerator> splits(SplittableGenerator source);
       
  1060 
       
  1061         /**
       
  1062          * Returns a stream producing the given {@code streamSize} number of
       
  1063          * new pseudorandom number generators, each of which implements the
       
  1064          * {@link SplittableGenerator} interface.
       
  1065          *
       
  1066          * @param streamSize the number of values to generate
       
  1067          * @param source a {@link SplittableGenerator} instance to be used instead
       
  1068          *               of this one as a source of pseudorandom bits used to
       
  1069          *               initialize the state of the new ones.
       
  1070          *
       
  1071          * @return a stream of {@link SplittableGenerator} objects
       
  1072          *
       
  1073          * @throws IllegalArgumentException if {@code streamSize} is
       
  1074          *         less than zero
       
  1075          */
       
  1076         Stream<SplittableGenerator> splits(long streamSize, SplittableGenerator source);
       
  1077 
       
  1078         /**
       
  1079          * Returns an effectively unlimited stream of new pseudorandom
       
  1080          * number generators, each of which implements the {@link RandomGenerator}
       
  1081          * interface.  Ideally the generators in the stream will appear
       
  1082          * to be statistically independent.
       
  1083          *
       
  1084          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1085          *
       
  1086          * @implNote The default implementation calls {@code splits()}.
       
  1087          */
       
  1088         default Stream<RandomGenerator> rngs() {
       
  1089             return this.splits().map(x -> (RandomGenerator)x);
       
  1090         }
       
  1091 
       
  1092         /**
       
  1093          * Returns a stream producing the given {@code streamSize} number of
       
  1094          * new pseudorandom number generators, each of which implements the
       
  1095          * {@link RandomGenerator} interface.  Ideally the generators in the stream will
       
  1096          * appear to be statistically independent.
       
  1097          *
       
  1098          * @param streamSize the number of generators to generate
       
  1099          *
       
  1100          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1101          *
       
  1102          * @throws IllegalArgumentException if {@code streamSize} is
       
  1103          *         less than zero
       
  1104          *
       
  1105          * @implNote The default implementation calls {@code splits(streamSize)}.
       
  1106          */
       
  1107         default Stream<RandomGenerator> rngs(long streamSize) {
       
  1108             return this.splits(streamSize).map(x -> (RandomGenerator)x);
       
  1109         }
       
  1110     }
       
  1111 
       
  1112     /**
       
  1113      * This interface is designed to provide a common protocol for objects that generate
       
  1114      * pseudorandom sequences of numbers (or Boolean values) and furthermore can easily <i>jump</i>
       
  1115      * forward (by a fixed amount) to a distant point in the state cycle.
       
  1116      * <p>
       
  1117      * Ideally, all {@link JumpableGenerator} objects produced by iterative jumping from a single
       
  1118      * original {@link JumpableGenerator} object are statistically independent of one another and
       
  1119      * individually uniform. In practice, one must settle for some approximation to independence and
       
  1120      * uniformity.  In particular, a specific implementation may assume that each generator in a
       
  1121      * stream produced by the {@code jumps} method is used to produce a number of values no larger
       
  1122      * than either 2<sup>64</sup> or the square root of its period.  Implementors are advised to use
       
  1123      * algorithms whose period is at least 2<sup>127</sup>.
       
  1124      * <p>
       
  1125      * Methods are provided to perform a single jump operation and also to produce a stream of
       
  1126      * generators produced from the original by iterative copying and jumping of internal state.  A
       
  1127      * typical strategy for a multithreaded application is to create a single {@link
       
  1128      * JumpableGenerator} object, calls its {@code jumps} method exactly once, and then parcel out
       
  1129      * generators from the resulting stream, one to each thread.  It is generally not a good idea to
       
  1130      * call {@code jump} on a generator that was itself produced by the {@code jumps} method,
       
  1131      * because the result may be a generator identical to another generator already produce by that
       
  1132      * call to the {@code jumps} method. For this reason, the return type of the {@code jumps}
       
  1133      * method is {@code Stream<RandomGenerator>} rather than {@code Stream<JumpableGenerator>}, even
       
  1134      * though the actual generator objects in that stream likely do also implement the {@link
       
  1135      * JumpableGenerator} interface.
       
  1136      * <p>
       
  1137      * An implementation of the {@link JumpableGenerator} interface must provide concrete
       
  1138      * definitions for the methods {@code nextInt()}, {@code nextLong}, {@code period()}, {@code
       
  1139      * copy()}, {@code jump()}, and {@code defaultJumpDistance()}. Default implementations are
       
  1140      * provided for all other methods.
       
  1141      * <p>
       
  1142      * Objects that implement {@link JumpableGenerator} are typically not cryptographically secure.
       
  1143      * Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
       
  1144      * pseudo-random number generator for use by security-sensitive applications.
       
  1145      *
       
  1146      * @since 14
       
  1147      */
       
  1148     public interface JumpableGenerator extends StreamableGenerator {
       
  1149 
       
  1150         /**
       
  1151          * Returns an instance of {@link JumpableGenerator} that utilizes the
       
  1152          * {@code name} algorithm.
       
  1153          *
       
  1154          * @param name  Name of random number generator algorithm
       
  1155          *
       
  1156          * @return An instance of {@link JumpableGenerator}
       
  1157          */
       
  1158         public static JumpableGenerator of(String name) {
       
  1159             Objects.requireNonNull(name);
       
  1160             return RandomGeneratorFactory.of(name, JumpableGenerator.class);
       
  1161         }
       
  1162 
       
  1163         /**
       
  1164          * Returns an instance of {@link JumpableGenerator} that utilizes the
       
  1165          * specified {@code algorithm}.
       
  1166          *
       
  1167          * @param algorithm  Random number generator algorithm
       
  1168          *
       
  1169          * @return An instance of {@link JumpableGenerator}
       
  1170          */
       
  1171         public static JumpableGenerator of(Algorithm algorithm) {
       
  1172             Objects.requireNonNull(algorithm);
       
  1173             return RandomGeneratorFactory.of(algorithm.toString(), JumpableGenerator.class);
       
  1174         }
       
  1175 
       
  1176         /**
       
  1177          * Returns a {@link RandomGeneratorFactory} that can produce instances
       
  1178          * of {@link JumpableGenerator} that utilizes the {@code name} algorithm.
       
  1179          *
       
  1180          * @param name  Name of random number generator algorithm
       
  1181          *
       
  1182          * @return {@link RandomGeneratorFactory} of {@link JumpableGenerator}
       
  1183          */
       
  1184         public static RandomGeneratorFactory<JumpableGenerator> factoryOf(String name) {
       
  1185             Objects.requireNonNull(name);
       
  1186             return RandomGeneratorFactory.factoryOf(name, JumpableGenerator.class);
       
  1187         }
       
  1188 
       
  1189         /**
       
  1190          * Returns a {@link RandomGeneratorFactory} that can produce instances
       
  1191          * of {@link JumpableGenerator} that utilizes the specified {@code algorithm}.
       
  1192          *
       
  1193          * @param algorithm  Random number generator algorithm
       
  1194          *
       
  1195          * @return {@link RandomGeneratorFactory} of {@link JumpableGenerator}
       
  1196          */
       
  1197         public static RandomGeneratorFactory<JumpableGenerator> factoryOf(Algorithm algorithm) {
       
  1198             Objects.requireNonNull(algorithm);
       
  1199             return RandomGeneratorFactory.factoryOf(algorithm.toString(), JumpableGenerator.class);
       
  1200         }
       
  1201 
       
  1202         /**
       
  1203          * Returns a new generator whose internal state is an exact copy of this generator (therefore
       
  1204          * their future behavior should be identical if subjected to the same series of operations).
       
  1205          *
       
  1206          * @return a new object that is a copy of this generator
       
  1207          */
       
  1208         JumpableGenerator copy();
       
  1209 
       
  1210         /**
       
  1211          * Alter the state of this pseudorandom number generator so as to jump forward a large, fixed
       
  1212          * distance (typically 2<sup>64</sup> or more) within its state cycle.
       
  1213          */
       
  1214         void jump();
       
  1215 
       
  1216         /**
       
  1217          * Returns the distance by which the {@code jump()} method will jump forward within the state
       
  1218          * cycle of this generator object.
       
  1219          *
       
  1220          * @return the default jump distance (as a {@code double} value)
       
  1221          */
       
  1222         double defaultJumpDistance();
       
  1223 
       
  1224         /**
       
  1225          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  1226          * implements the {@link RandomGenerator} interface.
       
  1227          *
       
  1228          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1229          *
       
  1230          * @implNote It is permitted to implement this method in a manner equivalent to
       
  1231          *         {@code jumps(Long.MAX_VALUE)}.
       
  1232          * @implNote The default implementation produces a sequential stream that  repeatedly
       
  1233          *         calls {@code copy()} and {@code jump()} on this generator, and the copies become the
       
  1234          *         generators produced by the stream.
       
  1235          */
       
  1236         default Stream<RandomGenerator> jumps() {
       
  1237             return Stream.generate(this::copyAndJump).sequential();
       
  1238         }
       
  1239 
       
  1240         /**
       
  1241          * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
       
  1242          * generators, each of which implements the {@link RandomGenerator} interface.
       
  1243          *
       
  1244          * @param streamSize the number of generators to generate
       
  1245          *
       
  1246          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1247          *
       
  1248          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1249          * @implNote The default implementation produces a sequential stream that  repeatedly
       
  1250          *         calls {@code copy()} and {@code jump()} on this generator, and the copies become the
       
  1251          *         generators produced by the stream.
       
  1252          */
       
  1253         default Stream<RandomGenerator> jumps(long streamSize) {
       
  1254             return jumps().limit(streamSize);
       
  1255         }
       
  1256 
       
  1257         /**
       
  1258          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  1259          * implements the {@link RandomGenerator} interface.  Ideally the generators in the stream
       
  1260          * will appear to be statistically independent.
       
  1261          *
       
  1262          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1263          *
       
  1264          * @implNote The default implementation calls {@code jumps()}.
       
  1265          */
       
  1266         default Stream<RandomGenerator> rngs() {
       
  1267             return this.jumps();
       
  1268         }
       
  1269 
       
  1270         /**
       
  1271          * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
       
  1272          * generators, each of which implements the {@link RandomGenerator} interface.  Ideally
       
  1273          * the generators in the stream will appear to be statistically independent.
       
  1274          *
       
  1275          * @param streamSize the number of generators to generate
       
  1276          *
       
  1277          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1278          *
       
  1279          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1280          * @implNote The default implementation calls {@code jumps(streamSize)}.
       
  1281          */
       
  1282         default Stream<RandomGenerator> rngs(long streamSize) {
       
  1283             return this.jumps(streamSize);
       
  1284         }
       
  1285 
       
  1286         /**
       
  1287          * Copy this generator, jump this generator forward, then return the copy.
       
  1288          *
       
  1289          * @return a copy of this generator object before the jump occurred
       
  1290          */
       
  1291         default RandomGenerator copyAndJump() {
       
  1292             RandomGenerator result = copy();
       
  1293             jump();
       
  1294             return result;
       
  1295         }
       
  1296 
       
  1297     }
       
  1298 
       
  1299     /**
       
  1300      * This interface is designed to provide a common protocol for objects that generate sequences
       
  1301      * of pseudorandom numbers (or Boolean values) and furthermore can easily not only jump but
       
  1302      * also
       
  1303      * <i>leap</i> to a very distant point in the state cycle.
       
  1304      * <p>
       
  1305      * Typically one will construct a series of {@link LeapableGenerator} objects by iterative
       
  1306      * leaping from a single original {@link LeapableGenerator} object, and then for each such
       
  1307      * object produce a subseries of objects by iterative jumping.  There is little conceptual
       
  1308      * difference between leaping and jumping, but typically a leap will be a very long jump in the
       
  1309      * state cycle (perhaps distance 2<sup>128</sup> or so).
       
  1310      * <p>
       
  1311      * Ideally, all {@link LeapableGenerator} objects produced by iterative leaping and jumping from
       
  1312      * a single original {@link LeapableGenerator} object are statistically independent of one
       
  1313      * another and individually uniform. In practice, one must settle for some approximation to
       
  1314      * independence and uniformity.  In particular, a specific implementation may assume that each
       
  1315      * generator in a stream produced by the {@code leaps} method is used to produce (by jumping) a
       
  1316      * number of objects no larger than 2<sup>64</sup>.  Implementors are advised to use algorithms
       
  1317      * whose period is at least 2<sup>191</sup>.
       
  1318      * <p>
       
  1319      * Methods are provided to perform a single leap operation and also to produce a stream of
       
  1320      * generators produced from the original by iterative copying and leaping of internal state.
       
  1321      * The generators produced must implement the {@link JumpableGenerator} interface but need not
       
  1322      * also implement the {@link LeapableGenerator} interface.  A typical strategy for a
       
  1323      * multithreaded application is to create a single {@link LeapableGenerator} object, calls its
       
  1324      * {@code leaps} method exactly once, and then parcel out generators from the resulting stream,
       
  1325      * one to each thread.  Then the {@code jumps} method of each such generator be called to
       
  1326      * produce a substream of generator objects.
       
  1327      * <p>
       
  1328      * An implementation of the {@link LeapableGenerator} interface must provide concrete
       
  1329      * definitions for the methods {@code nextInt()}, {@code nextLong}, {@code period()},
       
  1330      * {@code copy()}, {@code jump()}, {@code defaultJumpDistance()}, {@code leap()},
       
  1331      * and {@code defaultLeapDistance()}. Default implementations are provided for all other
       
  1332      * methods.
       
  1333      * <p>
       
  1334      * Objects that implement {@link LeapableGenerator} are typically not cryptographically secure.
       
  1335      * Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
       
  1336      * pseudo-random number generator for use by security-sensitive applications.
       
  1337      *
       
  1338      * @since 14
       
  1339      */
       
  1340     public interface LeapableGenerator extends JumpableGenerator {
       
  1341 
       
  1342         /**
       
  1343          * Returns an instance of {@link LeapableGenerator} that utilizes the
       
  1344          * {@code name} algorithm.
       
  1345          *
       
  1346          * @param name  Name of random number generator algorithm
       
  1347          *
       
  1348          * @return An instance of {@link LeapableGenerator}
       
  1349          */
       
  1350         public static LeapableGenerator of(String name) {
       
  1351             Objects.requireNonNull(name);
       
  1352             return RandomGeneratorFactory.of(name, LeapableGenerator.class);
       
  1353         }
       
  1354 
       
  1355         /**
       
  1356          * Returns an instance of {@link LeapableGenerator} that utilizes the
       
  1357          * specified {@code algorithm}.
       
  1358          *
       
  1359          * @param algorithm  Random number generator algorithm
       
  1360          *
       
  1361          * @return An instance of {@link LeapableGenerator}
       
  1362          */
       
  1363         public static LeapableGenerator of(Algorithm algorithm) {
       
  1364             Objects.requireNonNull(algorithm);
       
  1365             return RandomGeneratorFactory.of(algorithm.toString(), LeapableGenerator.class);
       
  1366         }
       
  1367 
       
  1368         /**
       
  1369          * Returns a {@link RandomGeneratorFactory} that can produce instances
       
  1370          * of {@link LeapableGenerator} that utilizes the {@code name} algorithm.
       
  1371          *
       
  1372          * @param name  Name of random number generator algorithm
       
  1373          *
       
  1374          * @return {@link RandomGeneratorFactory} of {@link LeapableGenerator}
       
  1375          */
       
  1376         public static RandomGeneratorFactory<LeapableGenerator> factoryOf(String name) {
       
  1377             Objects.requireNonNull(name);
       
  1378             return RandomGeneratorFactory.factoryOf(name, LeapableGenerator.class);
       
  1379         }
       
  1380 
       
  1381         /**
       
  1382          * Returns a {@link RandomGeneratorFactory} that can produce instances
       
  1383          * of {@link LeapableGenerator} that utilizes the specified {@code algorithm}.
       
  1384          *
       
  1385          * @param algorithm  Random number generator algorithm
       
  1386          *
       
  1387          * @return {@link RandomGeneratorFactory} of {@link LeapableGenerator}
       
  1388          */
       
  1389         public static RandomGeneratorFactory<LeapableGenerator> factoryOf(Algorithm algorithm) {
       
  1390             Objects.requireNonNull(algorithm);
       
  1391             return RandomGeneratorFactory.factoryOf(algorithm.toString(), LeapableGenerator.class);
       
  1392         }
       
  1393 
       
  1394         /**
       
  1395          * Returns a new generator whose internal state is an exact copy of this generator (therefore
       
  1396          * their future behavior should be identical if subjected to the same series of operations).
       
  1397          *
       
  1398          * @return a new object that is a copy of this generator
       
  1399          */
       
  1400         LeapableGenerator copy();
       
  1401 
       
  1402         /**
       
  1403          * Alter the state of this pseudorandom number generator so as to leap forward a large, fixed
       
  1404          * distance (typically 2<sup>96</sup> or more) within its state cycle.
       
  1405          */
       
  1406         void leap();
       
  1407 
       
  1408         /**
       
  1409          * Returns the distance by which the {@code leap()} method will leap forward within the state
       
  1410          * cycle of this generator object.
       
  1411          *
       
  1412          * @return the default leap distance (as a {@code double} value)
       
  1413          */
       
  1414         double defaultLeapDistance();
       
  1415 
       
  1416         /**
       
  1417          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  1418          * implements the {@link JumpableGenerator} interface.
       
  1419          *
       
  1420          * @return a stream of objects that implement the {@link JumpableGenerator} interface
       
  1421          *
       
  1422          * @implNote It is permitted to implement this method in a manner equivalent to {@code
       
  1423          *         leaps(Long.MAX_VALUE)}.
       
  1424          * @implNote The default implementation produces a sequential stream that  repeatedly
       
  1425          *         calls {@code copy()} and {@code leap()} on this generator, and the copies become the
       
  1426          *         generators produced by the stream.
       
  1427          */
       
  1428         default Stream<JumpableGenerator> leaps() {
       
  1429             return Stream.generate(this::copyAndLeap).sequential();
       
  1430         }
       
  1431 
       
  1432         /**
       
  1433          * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
       
  1434          * generators, each of which implements the {@link JumpableGenerator} interface.
       
  1435          *
       
  1436          * @param streamSize the number of generators to generate
       
  1437          *
       
  1438          * @return a stream of objects that implement the {@link JumpableGenerator} interface
       
  1439          *
       
  1440          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1441          * @implNote The default implementation produces a sequential stream that  repeatedly
       
  1442          *         calls {@code copy()} and {@code leap()} on this generator, and the copies become the
       
  1443          *         generators produced by the stream.
       
  1444          */
       
  1445         default Stream<JumpableGenerator> leaps(long streamSize) {
       
  1446             return leaps().limit(streamSize);
       
  1447         }
       
  1448 
       
  1449         /**
       
  1450          * Copy this generator, leap this generator forward, then return the copy.
       
  1451          *
       
  1452          * @return a copy of this generator object before the leap occurred
       
  1453          */
       
  1454         default JumpableGenerator copyAndLeap() {
       
  1455             JumpableGenerator result = copy();
       
  1456             leap();
       
  1457             return result;
       
  1458         }
       
  1459 
       
  1460     }
       
  1461 
       
  1462     /**
       
  1463      * This interface is designed to provide a common protocol for objects that generate sequences
       
  1464      * of pseudorandom numbers (or Boolean values) and furthermore can easily <i>jump</i> to an
       
  1465      * arbitrarily specified distant point in the state cycle.
       
  1466      * <p>
       
  1467      * Ideally, all {@link ArbitrarilyJumpableGenerator} objects produced by iterative jumping from
       
  1468      * a single original {@link ArbitrarilyJumpableGenerator} object are statistically independent
       
  1469      * of one another and individually uniform, provided that they do not traverse overlapping
       
  1470      * portions of the state cycle. In practice, one must settle for some approximation to
       
  1471      * independence and uniformity.  In particular, a specific implementation may assume that each
       
  1472      * generator in a stream produced by the {@code jumps} method is used to produce a number of
       
  1473      * values no larger than the jump distance specified.  Implementors are advised to use
       
  1474      * algorithms whose period is at least 2<sup>127</sup>.
       
  1475      * <p>
       
  1476      * For many applications, it suffices to jump forward by a power of two or some small multiple
       
  1477      * of a power of two, but this power of two may not be representable as a {@code long} value.
       
  1478      * To avoid the use of {@link java.math.BigInteger} values as jump distances, {@code double}
       
  1479      * values are used instead.
       
  1480      * <p>
       
  1481      * Methods are provided to perform a single jump operation and also to produce a stream of
       
  1482      * generators produced from the original by iterative copying and jumping of internal state.  A
       
  1483      * typical strategy for a multithreaded application is to create a single
       
  1484      * {@link ArbitrarilyJumpableGenerator} object, call its {@code jumps} method exactly once, and
       
  1485      * then parcel out generators from the resulting stream, one to each thread.  However, each
       
  1486      * generator produced also has type {@link ArbitrarilyJumpableGenerator}; with care, different
       
  1487      * jump distances can be used to traverse the entire state cycle in various ways.
       
  1488      * <p>
       
  1489      * An implementation of the {@link ArbitrarilyJumpableGenerator} interface must provide concrete
       
  1490      * definitions for the methods {@code nextInt()}, {@code nextLong}, {@code period()},
       
  1491      * {@code copy()}, {@code jump(double)}, {@code defaultJumpDistance()}, and
       
  1492      * {@code defaultLeapDistance()}. Default implementations are provided for all other methods.
       
  1493      * Perhaps the most convenient way to implement this interface is to extend the abstract class
       
  1494      * {@link ArbitrarilyJumpableGenerator}, which provides spliterator-based implementations of the
       
  1495      * methods {@code ints}, {@code longs}, {@code doubles}, {@code rngs}, {@code jumps}, and
       
  1496      * {@code leaps}.
       
  1497      * <p>
       
  1498      * Objects that implement {@link ArbitrarilyJumpableGenerator} are typically not
       
  1499      * cryptographically secure. Consider instead using {@link java.security.SecureRandom} to get a
       
  1500      * cryptographically secure pseudo-random number generator for use by security-sensitive
       
  1501      * applications.
       
  1502      *
       
  1503      * @since 14
       
  1504      */
       
  1505     public interface ArbitrarilyJumpableGenerator extends LeapableGenerator {
       
  1506 
       
  1507         /**
       
  1508          * Returns an instance of {@link ArbitrarilyJumpableGenerator} that utilizes the
       
  1509          * {@code name} algorithm.
       
  1510          *
       
  1511          * @param name  Name of random number generator algorithm
       
  1512          *
       
  1513          * @return An instance of {@link ArbitrarilyJumpableGenerator}
       
  1514          */
       
  1515         public static ArbitrarilyJumpableGenerator of(String name) {
       
  1516             Objects.requireNonNull(name);
       
  1517             return RandomGeneratorFactory.of(name, ArbitrarilyJumpableGenerator.class);
       
  1518         }
       
  1519 
       
  1520         /**
       
  1521          * Returns an instance of {@link ArbitrarilyJumpableGenerator} that utilizes the
       
  1522          * specified {@code algorithm}.
       
  1523          *
       
  1524          * @param algorithm  Random number generator algorithm
       
  1525          *
       
  1526          * @return An instance of {@link ArbitrarilyJumpableGenerator}
       
  1527          */
       
  1528         public static ArbitrarilyJumpableGenerator of(Algorithm algorithm) {
       
  1529             Objects.requireNonNull(algorithm);
       
  1530             return RandomGeneratorFactory.of(algorithm.toString(), ArbitrarilyJumpableGenerator.class);
       
  1531         }
       
  1532 
       
  1533         /**
       
  1534          * Returns a {@link RandomGeneratorFactory} that can produce instances
       
  1535          * of {@link ArbitrarilyJumpableGenerator} that utilizes the {@code name} algorithm.
       
  1536          *
       
  1537          * @param name  Name of random number generator algorithm
       
  1538          *
       
  1539          * @return {@link RandomGeneratorFactory} of {@link ArbitrarilyJumpableGenerator}
       
  1540          */
       
  1541         public static RandomGeneratorFactory<ArbitrarilyJumpableGenerator> factoryOf(String name) {
       
  1542             Objects.requireNonNull(name);
       
  1543             return RandomGeneratorFactory.factoryOf(name, ArbitrarilyJumpableGenerator.class);
       
  1544         }
       
  1545 
       
  1546         /**
       
  1547          * Returns a {@link RandomGeneratorFactory} that can produce instances
       
  1548          * of {@link ArbitrarilyJumpableGenerator} that utilizes the specified {@code algorithm}.
       
  1549          *
       
  1550          * @param algorithm  Random number generator algorithm
       
  1551          *
       
  1552          * @return {@link RandomGeneratorFactory} of {@link ArbitrarilyJumpableGenerator}
       
  1553          */
       
  1554         public static RandomGeneratorFactory<ArbitrarilyJumpableGenerator> factoryOf(Algorithm algorithm) {
       
  1555             Objects.requireNonNull(algorithm);
       
  1556             return RandomGeneratorFactory.factoryOf(algorithm.toString(), ArbitrarilyJumpableGenerator.class);
       
  1557         }
       
  1558 
       
  1559         /**
       
  1560          * Returns a new generator whose internal state is an exact copy of this generator (therefore
       
  1561          * their future behavior should be identical if subjected to the same series of operations).
       
  1562          *
       
  1563          * @return a new object that is a copy of this generator
       
  1564          */
       
  1565         ArbitrarilyJumpableGenerator copy();
       
  1566 
       
  1567         /**
       
  1568          * Alter the state of this pseudorandom number generator so as to jump forward a distance equal
       
  1569          * to 2<sup>{@code logDistance}</sup> within its state cycle.
       
  1570          *
       
  1571          * @param logDistance the base-2 logarithm of the distance to jump forward within the state
       
  1572          *                    cycle
       
  1573          *
       
  1574          * @throws IllegalArgumentException if {@code logDistance} is NaN or negative, or if
       
  1575          *                                  2<sup>{@code logDistance}</sup> is greater than the period
       
  1576          *                                  of this generator
       
  1577          */
       
  1578         void jumpPowerOfTwo(int logDistance);
       
  1579 
       
  1580         /**
       
  1581          * Alter the state of this pseudorandom number generator so as to jump forward a specified
       
  1582          * distance within its state cycle.
       
  1583          *
       
  1584          * @param distance the distance to jump forward within the state cycle
       
  1585          *
       
  1586          * @throws IllegalArgumentException if {@code distance} is Nan, negative, or greater than the
       
  1587          *                                  period of this generator
       
  1588          */
       
  1589         void jump(double distance);
       
  1590 
       
  1591         /**
       
  1592          * Alter the state of this pseudorandom number generator so as to jump forward a large, fixed
       
  1593          * distance (typically 2<sup>64</sup> or more) within its state cycle.  The distance used is
       
  1594          * that returned by method {@code defaultJumpDistance()}.
       
  1595          */
       
  1596         default void jump() { jump(defaultJumpDistance()); }
       
  1597 
       
  1598         /**
       
  1599          * Returns an effectively unlimited stream of new pseudorandom number generators, each of
       
  1600          * which implements the {@link ArbitrarilyJumpableGenerator} interface, produced by jumping
       
  1601          * copies of this generator by different integer multiples of the specified jump distance.
       
  1602          *
       
  1603          * @param distance a distance to jump forward within the state cycle
       
  1604          *
       
  1605          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1606          *
       
  1607          * @implNote This method is implemented to be equivalent to {@code jumps(Long.MAX_VALUE)}.
       
  1608          */
       
  1609         default Stream<ArbitrarilyJumpableGenerator> jumps(double distance) {
       
  1610             return Stream.generate(() -> copyAndJump(distance)).sequential();
       
  1611         }
       
  1612 
       
  1613         /**
       
  1614          * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
       
  1615          * generators, each of which implements the {@link ArbitrarilyJumpableGenerator} interface,
       
  1616          * produced by jumping copies of this generator by different integer multiples of the
       
  1617          * specified jump distance.
       
  1618          *
       
  1619          * @param streamSize the number of generators to generate
       
  1620          * @param distance   a distance to jump forward within the state cycle
       
  1621          *
       
  1622          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1623          *
       
  1624          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1625          */
       
  1626         default Stream<ArbitrarilyJumpableGenerator> jumps(long streamSize, double distance) {
       
  1627             return jumps(distance).limit(streamSize);
       
  1628         }
       
  1629 
       
  1630         /**
       
  1631          * Alter the state of this pseudorandom number generator so as to jump forward a very large,
       
  1632          * fixed distance (typically 2<sup>128</sup> or more) within its state cycle.  The distance
       
  1633          * used is that returned by method {@code defaultJLeapDistance()}.
       
  1634          */
       
  1635         default void leap() { jump(defaultLeapDistance()); }
       
  1636 
       
  1637         /**
       
  1638          * Copy this generator, jump this generator forward, then return the copy.
       
  1639          *
       
  1640          * @param distance a distance to jump forward within the state cycle
       
  1641          *
       
  1642          * @return a copy of this generator object before the jump occurred
       
  1643          */
       
  1644         default ArbitrarilyJumpableGenerator copyAndJump(double distance) {
       
  1645             ArbitrarilyJumpableGenerator result = copy();
       
  1646             jump(distance);
       
  1647             return result;
       
  1648         }
       
  1649 
       
  1650     }
       
  1651 }