There are lots of APIs out there that take an instance of Random as a source of randomness provided by the caller. In fact, they're using it as if it were a RandomGenerator, except that interface didn't exist until recently.
APIs in Java SE that consume Random this way include:
BigInteger.probablePrime
BigInteger constructors
Collections.shuffle
Overloads of these APIs that consume RandomGenerator could be provided. That wouldn't be terrible, though it would add some clutter to the API. (The existing overloads couldn't be removed, because of binary compatibility.) External APIs that consume Random are in a more difficult problem. They too could add RandomGenerator-bearing overloads, but that's difficult if they want to maintain compatibility with older Java releases that lack RandomGenerator.
It would be helpful for these cases to have some kind of static factory method that produces an adapter: it would consume a RandomGenerator instance and return an instance of a subclass of java.util.Random that simply delegates most of its method implementations to the underlying RandomGenerator.
The only methods on Random that are not present on RandomGenerator, that thus could not be implemented by delegating to RandomGenerator, are next(int bits) and setSeed().
The next(int bits) method is protected and is intended to be overridden by subclasses as the source of randomness for all the other methods. This is irrelevant, as the adapter class should be non-public and thus not subclassable, and its main random-returning APIs will be implemented in terms of RandomGenerator instead of next(int bits).
The other issue is what to do with setSeed(). I note that ThreadLocalRandom's implementation throws UnsupportedOperationException, so that seems like a sensible thing to do. Things that consume randomness should never call setSeed; if they attempt to replay a random sequence by calling setSeed, that can't be supported by this adapter anyway, so UOE is appropriate.
A possibility is to add the following to java.util.Random:
public static Random from(RandomGenerator)
which would return an instance of some private subclass that wraps the RandomGenerator instance. Usage would be:
Collections.shuffle(list, Random.from(RandomGenerator.of("L64X128MixRandom")));
Alternatively, this could be a default method asRandom() or similar on RandomGenerator. There wouldn't be a need for RG implementations to override it, but it might make things more fluent:
Collections.shuffle(list, RandomGenerator.of("L64X128MixRandom").asRandom());
APIs in Java SE that consume Random this way include:
BigInteger.probablePrime
BigInteger constructors
Collections.shuffle
Overloads of these APIs that consume RandomGenerator could be provided. That wouldn't be terrible, though it would add some clutter to the API. (The existing overloads couldn't be removed, because of binary compatibility.) External APIs that consume Random are in a more difficult problem. They too could add RandomGenerator-bearing overloads, but that's difficult if they want to maintain compatibility with older Java releases that lack RandomGenerator.
It would be helpful for these cases to have some kind of static factory method that produces an adapter: it would consume a RandomGenerator instance and return an instance of a subclass of java.util.Random that simply delegates most of its method implementations to the underlying RandomGenerator.
The only methods on Random that are not present on RandomGenerator, that thus could not be implemented by delegating to RandomGenerator, are next(int bits) and setSeed().
The next(int bits) method is protected and is intended to be overridden by subclasses as the source of randomness for all the other methods. This is irrelevant, as the adapter class should be non-public and thus not subclassable, and its main random-returning APIs will be implemented in terms of RandomGenerator instead of next(int bits).
The other issue is what to do with setSeed(). I note that ThreadLocalRandom's implementation throws UnsupportedOperationException, so that seems like a sensible thing to do. Things that consume randomness should never call setSeed; if they attempt to replay a random sequence by calling setSeed, that can't be supported by this adapter anyway, so UOE is appropriate.
A possibility is to add the following to java.util.Random:
public static Random from(RandomGenerator)
which would return an instance of some private subclass that wraps the RandomGenerator instance. Usage would be:
Collections.shuffle(list, Random.from(RandomGenerator.of("L64X128MixRandom")));
Alternatively, this could be a default method asRandom() or similar on RandomGenerator. There wouldn't be a need for RG implementations to override it, but it might make things more fluent:
Collections.shuffle(list, RandomGenerator.of("L64X128MixRandom").asRandom());
- csr for
-
JDK-8282928 provide adapter from RandomGenerator to Random
-
- Closed
-
- relates to
-
JDK-8154225 "java.util.Random": constructor calls an overridable method
-
- Closed
-
-
JDK-8283319 Replace the Random class type with the RandomGenerator interface
-
- Closed
-