--- a/src/java.base/share/classes/java/util/Random.java Fri Jul 26 15:37:05 2019 -0300
+++ b/src/java.base/share/classes/java/util/Random.java Wed Aug 07 15:35:55 2019 -0300
@@ -31,18 +31,13 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.DoubleConsumer;
-import java.util.function.Function;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
-import java.util.Objects;
import java.util.random.RandomGenerator;
import java.util.random.RandomSupport;
import java.util.random.RandomSupport.AbstractSpliteratorGenerator;
import java.util.random.RandomSupport.RandomSpliterator;
-import java.util.ServiceLoader;
-import java.util.ServiceLoader.Provider;
import java.util.Spliterator;
-import java.util.stream.Collectors;
/**
* An instance of this class is used to generate a stream of
@@ -501,47 +496,6 @@
}
/**
- * Creates a new random number generator that uses the random number generator algorithm
- * specified by name. The seed of the random number generator to a value very likely to be
- * distinct from any other invocation.
- *
- * @param name name of random number generator algorithm to use.
- *
- * @return an instance of random number generator.
- *
- * @throws IllegalArgumentException if {@code name} is an unknown random number generator
- *
- * @since 14
- */
- public static RandomGenerator byName(String name) throws IllegalArgumentException {
- Objects.requireNonNull(name);
- Map<String, Provider<RandomGenerator>> rngs = getGeneratorMap();
- Provider<RandomGenerator> provider = rngs.get(name.toUpperCase());
- if (provider == null) {
- throw new IllegalArgumentException(name + " is an unknown random number generator");
- }
- return provider.get();
- }
-
- private static Map<String, Provider<RandomGenerator>> rngMap;
-
- private static Map<String, Provider<RandomGenerator>> getGeneratorMap() {
- if (rngMap == null) {
- synchronized (Random.class) {
- if (rngMap == null) {
- rngMap = ServiceLoader
- .load(RandomGenerator.class)
- .stream()
- .filter(p -> !p.type().isInterface())
- .collect(Collectors.toMap(p -> p.type().getSimpleName().toUpperCase(),
- Function.identity()));
- }
- }
- }
- return rngMap;
- }
-
- /**
* Serializable fields for Random.
*
* @serialField seed long
--- a/src/java.base/share/classes/java/util/random/RandomGenerator.java Fri Jul 26 15:37:05 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/RandomGenerator.java Wed Aug 07 15:35:55 2019 -0300
@@ -26,11 +26,11 @@
package java.util.random;
import java.math.BigInteger;
+import java.util.Objects;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
/**
* The {@link RandomGenerator} interface is designed to provide a common protocol for objects
@@ -90,6 +90,122 @@
public interface RandomGenerator {
/**
+ * Supported randpm number Algorithms.
+ */
+ public enum Algorithm {
+ /**
+ * L32X64MixRandom algorithm
+ */
+ L32X64MixRandom("L32X64MixRandom"),
+ /**
+ * L64X1024MixRandom algorithm
+ */
+ L64X1024MixRandom("L64X1024MixRandom"),
+ /**
+ * L64X1024Random algorithm
+ */
+ L64X1024Random("L64X1024Random"),
+ /**
+ * L64X128MixRandom algorithm
+ */
+ L64X128MixRandom("L64X128MixRandom"),
+ /**
+ * L64X128Random algorithm
+ */
+ L64X128Random("L64X128Random"),
+ /**
+ * L64X256MixRandom algorithm
+ */
+ L64X256MixRandom("L64X256MixRandom"),
+ /**
+ * L64X256Random algorithm
+ */
+ L64X256Random("L64X256Random"),
+ /**
+ * L128X256MixRandom algorithm
+ */
+ L128X256MixRandom("L128X256MixRandom"),
+ /**
+ * MRG32k3a algorithm
+ */
+ MRG32k3a("MRG32k3a"),
+ /**
+ * Xoroshiro128Plus algorithm
+ */
+ Xoroshiro128Plus("Xoroshiro128Plus"),
+ /**
+ * Xoroshiro128StarStar algorithm
+ */
+ Xoroshiro128StarStar("Xoroshiro128StarStar"),
+ /**
+ * Xoshiro256StarStar algorithm
+ */
+ Xoshiro256StarStar("Xoshiro256StarStar");
+
+ private String name;
+
+ Algorithm(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return name;
+ }
+ }
+
+ /**
+ * Returns an instance of {@link RandomGenerator} that utilizes the
+ * {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return An instance of {@link RandomGenerator}
+ */
+ public static RandomGenerator of(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.of(name, RandomGenerator.class);
+ }
+
+ /**
+ * Returns an instance of {@link RandomGenerator} that utilizes the
+ * specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return An instance of {@link RandomGenerator}
+ */
+ public static RandomGenerator of(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.of(algorithm.toString(), RandomGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link RandomGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return Factory of {@link RandomGenerator}
+ */
+ public static RandomGeneratorFactory<RandomGenerator> factoryOf(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.factoryOf(name, RandomGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link RandomGenerator} that utilizes the specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return Factory of {@link RandomGenerator}
+ */
+ public static RandomGeneratorFactory<RandomGenerator> factoryOf(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.factoryOf(algorithm.toString(), RandomGenerator.class);
+ }
+
+ /**
* Returns an effectively unlimited stream of pseudorandomly chosen
* {@code double} values.
*
@@ -672,6 +788,59 @@
* @since 14
*/
public interface StreamableGenerator extends RandomGenerator {
+
+ /**
+ * Returns an instance of {@link StreamableGenerator} that utilizes the
+ * {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return An instance of {@link StreamableGenerator}
+ */
+ public static StreamableGenerator of(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.of(name, StreamableGenerator.class);
+ }
+
+ /**
+ * Returns an instance of {@link StreamableGenerator} that utilizes the
+ * specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return An instance of {@link StreamableGenerator}
+ */
+ public static StreamableGenerator of(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.of(algorithm.toString(), StreamableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link StreamableGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return Factory of {@link StreamableGenerator}
+ */
+ public static RandomGeneratorFactory<StreamableGenerator> factoryOf(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.factoryOf(name, StreamableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link StreamableGenerator} that utilizes the specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return Factory of {@link StreamableGenerator}
+ */
+ public static RandomGeneratorFactory<StreamableGenerator> factoryOf(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.factoryOf(algorithm.toString(), StreamableGenerator.class);
+ }
+
/**
* Returns an effectively unlimited stream of objects, each of
* which implements the {@link RandomGenerator} interface. Ideally the
@@ -748,6 +917,58 @@
public interface SplittableGenerator extends StreamableGenerator {
/**
+ * Returns an instance of {@link SplittableGenerator} that utilizes the
+ * {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return An instance of {@link SplittableGenerator}
+ */
+ public static SplittableGenerator of(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.of(name, SplittableGenerator.class);
+ }
+
+ /**
+ * Returns an instance of {@link SplittableGenerator} that utilizes the
+ * specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return An instance of {@link SplittableGenerator}
+ */
+ public static SplittableGenerator of(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.of(algorithm.toString(), SplittableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link SplittableGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return Factory of {@link SplittableGenerator}
+ */
+ public static RandomGeneratorFactory<SplittableGenerator> factoryOf(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.factoryOf(name, SplittableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link SplittableGenerator} that utilizes the specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return Factory of {@link SplittableGenerator}
+ */
+ public static RandomGeneratorFactory<SplittableGenerator> factoryOf(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.factoryOf(algorithm.toString(), SplittableGenerator.class);
+ }
+
+ /**
* Returns a new pseudorandom number generator, split off from
* this one, that implements the {@link RandomGenerator} and {@link SplittableGenerator}
* interfaces.
@@ -910,6 +1131,59 @@
* @since 14
*/
public interface JumpableGenerator extends StreamableGenerator {
+
+ /**
+ * Returns an instance of {@link JumpableGenerator} that utilizes the
+ * {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return An instance of {@link JumpableGenerator}
+ */
+ public static JumpableGenerator of(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.of(name, JumpableGenerator.class);
+ }
+
+ /**
+ * Returns an instance of {@link JumpableGenerator} that utilizes the
+ * specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return An instance of {@link JumpableGenerator}
+ */
+ public static JumpableGenerator of(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.of(algorithm.toString(), JumpableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link JumpableGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return Factory of {@link JumpableGenerator}
+ */
+ public static RandomGeneratorFactory<JumpableGenerator> factoryOf(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.factoryOf(name, JumpableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link JumpableGenerator} that utilizes the specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return Factory of {@link JumpableGenerator}
+ */
+ public static RandomGeneratorFactory<JumpableGenerator> factoryOf(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.factoryOf(algorithm.toString(), JumpableGenerator.class);
+ }
+
/**
* Returns a new generator whose internal state is an exact copy of this generator (therefore
* their future behavior should be identical if subjected to the same series of operations).
@@ -1046,6 +1320,59 @@
* @since 14
*/
public interface LeapableGenerator extends JumpableGenerator {
+
+ /**
+ * Returns an instance of {@link LeapableGenerator} that utilizes the
+ * {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return An instance of {@link LeapableGenerator}
+ */
+ public static LeapableGenerator of(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.of(name, LeapableGenerator.class);
+ }
+
+ /**
+ * Returns an instance of {@link LeapableGenerator} that utilizes the
+ * specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return An instance of {@link LeapableGenerator}
+ */
+ public static LeapableGenerator of(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.of(algorithm.toString(), LeapableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link LeapableGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return Factory of {@link LeapableGenerator}
+ */
+ public static RandomGeneratorFactory<LeapableGenerator> factoryOf(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.factoryOf(name, LeapableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link LeapableGenerator} that utilizes the specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return Factory of {@link LeapableGenerator}
+ */
+ public static RandomGeneratorFactory<LeapableGenerator> factoryOf(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.factoryOf(algorithm.toString(), LeapableGenerator.class);
+ }
+
/**
* Returns a new generator whose internal state is an exact copy of this generator (therefore
* their future behavior should be identical if subjected to the same series of operations).
@@ -1155,6 +1482,59 @@
* @since 14
*/
public interface ArbitrarilyJumpableGenerator extends LeapableGenerator {
+
+ /**
+ * Returns an instance of {@link ArbitrarilyJumpableGenerator} that utilizes the
+ * {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return An instance of {@link ArbitrarilyJumpableGenerator}
+ */
+ public static ArbitrarilyJumpableGenerator of(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.of(name, ArbitrarilyJumpableGenerator.class);
+ }
+
+ /**
+ * Returns an instance of {@link ArbitrarilyJumpableGenerator} that utilizes the
+ * specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return An instance of {@link ArbitrarilyJumpableGenerator}
+ */
+ public static ArbitrarilyJumpableGenerator of(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.of(algorithm.toString(), ArbitrarilyJumpableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link ArbitrarilyJumpableGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number generator algorithm
+ *
+ * @return Factory of {@link ArbitrarilyJumpableGenerator}
+ */
+ public static RandomGeneratorFactory<ArbitrarilyJumpableGenerator> factoryOf(String name) {
+ Objects.requireNonNull(name);
+ return RandomGeneratorFactory.factoryOf(name, ArbitrarilyJumpableGenerator.class);
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that can produce instances
+ * of {@link ArbitrarilyJumpableGenerator} that utilizes the specified {@code algorithm}.
+ *
+ * @param algorithm Random number generator algorithm
+ *
+ * @return Factory of {@link ArbitrarilyJumpableGenerator}
+ */
+ public static RandomGeneratorFactory<ArbitrarilyJumpableGenerator> factoryOf(Algorithm algorithm) {
+ Objects.requireNonNull(algorithm);
+ return RandomGeneratorFactory.factoryOf(algorithm.toString(), ArbitrarilyJumpableGenerator.class);
+ }
+
/**
* Returns a new generator whose internal state is an exact copy of this generator (therefore
* their future behavior should be identical if subjected to the same series of operations).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java Wed Aug 07 15:35:55 2019 -0300
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.util.random;
+
+import java.util.function.Function;
+import java.util.Map;
+import java.util.Objects;
+import java.util.ServiceLoader;
+import java.util.ServiceLoader.Provider;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+/**
+ * This is a factory class for generating random number generators of a specific
+ * catagory and algorithm.
+ */
+public class RandomGeneratorFactory<T> {
+ /**
+ * Instance provider class of random number algorithm.
+ */
+ private final Provider<T> provider;
+
+ /**
+ * Map of provider classes.
+ */
+ private static Map<String, Provider<RandomGenerator>> providerMap;
+
+ /**
+ * Private constructor.
+ *
+ * @param provider Provider class to wrap.
+ */
+ private RandomGeneratorFactory(Provider<T> provider) {
+ this.provider = provider;
+ }
+
+ /**
+ * Returns the provider map, lazily constructing map on first call.
+ *
+ * @return Map of provider classes.
+ */
+ private static Map<String, Provider<RandomGenerator>> getProviderMap() {
+ if (providerMap == null) {
+ synchronized (RandomGeneratorFactory.class) {
+ if (providerMap == null) {
+ providerMap =
+ ServiceLoader
+ .load(RandomGenerator.class)
+ .stream()
+ .filter(p -> !p.type().isInterface())
+ .collect(Collectors.toMap(p -> p.type().getSimpleName().toUpperCase(),
+ Function.identity()));
+ }
+ }
+ }
+ return providerMap;
+ }
+
+ private static Provider<RandomGenerator> findProvider(String name, Class<? extends RandomGenerator> category)
+ throws IllegalArgumentException {
+ Map<String, Provider<RandomGenerator>> pm = getProviderMap();
+ Provider<RandomGenerator> provider = pm.get(name.toUpperCase());
+ if (provider == null || provider.type().isAssignableFrom(category)) {
+ throw new IllegalArgumentException(name + " is an unknown random number generator");
+ }
+ return provider;
+ }
+
+ /**
+ * Returns a {@link RandomGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number algorithm to use
+ * @param category Sub-interface of {@link RandomGenerator} to type check
+ * @param <T> Sub-interface of {@link RandomGenerator} to produce
+ * @return An instance of {@link RandomGenerator}
+ * @throws IllegalArgumentException when either the name or category is null
+ */
+ static <T> T of(String name, Class<? extends RandomGenerator> category)
+ throws IllegalArgumentException {
+ @SuppressWarnings("unchecked")
+ T uncheckedRandomGenerator = (T)findProvider(name, category).get();
+ return uncheckedRandomGenerator;
+ }
+
+ /**
+ * Returns a {@link RandomGeneratorFactory} that will produce instances
+ * of {@link RandomGenerator} that utilizes the {@code name} algorithm.
+ *
+ * @param name Name of random number algorithm to use
+ * @param category Sub-interface of {@link RandomGenerator} to type check
+ * @param <T> Sub-interface of {@link RandomGenerator} to produce
+ * @return Factory of {@link RandomGenerator}
+ * @throws IllegalArgumentException when either the name or category is null
+ */
+ static <T> RandomGeneratorFactory<T> factoryOf(String name, Class<? extends RandomGenerator> category)
+ throws IllegalArgumentException {
+ @SuppressWarnings("unchecked")
+ Provider<T> uncheckedProvider = (Provider<T>)findProvider(name, category);
+ return new RandomGeneratorFactory<T>(uncheckedProvider);
+ }
+
+ /**
+ * Create an instance of {@link RandomGenerator}.
+ *
+ * @return Instance of {@link RandomGenerator}.
+ */
+ public T create() {
+ return provider.get();
+ }
+}
+
+