29 |
29 |
30 import java.io.*; |
30 import java.io.*; |
31 import java.math.BigInteger; |
31 import java.math.BigInteger; |
32 import java.util.concurrent.atomic.AtomicLong; |
32 import java.util.concurrent.atomic.AtomicLong; |
33 import java.util.function.DoubleConsumer; |
33 import java.util.function.DoubleConsumer; |
34 import java.util.function.Function; |
|
35 import java.util.function.IntConsumer; |
34 import java.util.function.IntConsumer; |
36 import java.util.function.LongConsumer; |
35 import java.util.function.LongConsumer; |
37 import java.util.Objects; |
|
38 import java.util.random.RandomGenerator; |
36 import java.util.random.RandomGenerator; |
39 import java.util.random.RandomSupport; |
37 import java.util.random.RandomSupport; |
40 import java.util.random.RandomSupport.AbstractSpliteratorGenerator; |
38 import java.util.random.RandomSupport.AbstractSpliteratorGenerator; |
41 import java.util.random.RandomSupport.RandomSpliterator; |
39 import java.util.random.RandomSupport.RandomSpliterator; |
42 import java.util.ServiceLoader; |
|
43 import java.util.ServiceLoader.Provider; |
|
44 import java.util.Spliterator; |
40 import java.util.Spliterator; |
45 import java.util.stream.Collectors; |
|
46 |
41 |
47 /** |
42 /** |
48 * An instance of this class is used to generate a stream of |
43 * An instance of this class is used to generate a stream of |
49 * pseudorandom numbers. The class uses a 48-bit seed, which is |
44 * pseudorandom numbers. The class uses a 48-bit seed, which is |
50 * modified using a linear congruential formula. (See Donald Knuth, |
45 * modified using a linear congruential formula. (See Donald Knuth, |
499 return v1 * multiplier; |
494 return v1 * multiplier; |
500 } |
495 } |
501 } |
496 } |
502 |
497 |
503 /** |
498 /** |
504 * Creates a new random number generator that uses the random number generator algorithm |
|
505 * specified by name. The seed of the random number generator to a value very likely to be |
|
506 * distinct from any other invocation. |
|
507 * |
|
508 * @param name name of random number generator algorithm to use. |
|
509 * |
|
510 * @return an instance of random number generator. |
|
511 * |
|
512 * @throws IllegalArgumentException if {@code name} is an unknown random number generator |
|
513 * |
|
514 * @since 14 |
|
515 */ |
|
516 public static RandomGenerator byName(String name) throws IllegalArgumentException { |
|
517 Objects.requireNonNull(name); |
|
518 Map<String, Provider<RandomGenerator>> rngs = getGeneratorMap(); |
|
519 Provider<RandomGenerator> provider = rngs.get(name.toUpperCase()); |
|
520 if (provider == null) { |
|
521 throw new IllegalArgumentException(name + " is an unknown random number generator"); |
|
522 } |
|
523 return provider.get(); |
|
524 } |
|
525 |
|
526 private static Map<String, Provider<RandomGenerator>> rngMap; |
|
527 |
|
528 private static Map<String, Provider<RandomGenerator>> getGeneratorMap() { |
|
529 if (rngMap == null) { |
|
530 synchronized (Random.class) { |
|
531 if (rngMap == null) { |
|
532 rngMap = ServiceLoader |
|
533 .load(RandomGenerator.class) |
|
534 .stream() |
|
535 .filter(p -> !p.type().isInterface()) |
|
536 .collect(Collectors.toMap(p -> p.type().getSimpleName().toUpperCase(), |
|
537 Function.identity())); |
|
538 } |
|
539 } |
|
540 } |
|
541 return rngMap; |
|
542 } |
|
543 |
|
544 /** |
|
545 * Serializable fields for Random. |
499 * Serializable fields for Random. |
546 * |
500 * |
547 * @serialField seed long |
501 * @serialField seed long |
548 * seed for random computations |
502 * seed for random computations |
549 * @serialField nextNextGaussian double |
503 * @serialField nextNextGaussian double |