Class RandomWrapper
- java.lang.Object
-
- java.util.Random
-
- io.github.pr0methean.betterrandom.prng.BaseRandom
-
- io.github.pr0methean.betterrandom.prng.adapter.RandomWrapper
-
- All Implemented Interfaces:
ByteArrayReseedableRandom
,EntropyCountingRandom
,Java8CompatRandom
,RepeatableRandom
,Dumpable
,Serializable
- Direct Known Subclasses:
EntropyBlockingRandomWrapper
,ThreadLocalRandomWrapper
public class RandomWrapper extends BaseRandom
Wraps any
Random
as aRepeatableRandom
andByteArrayReseedableRandom
. Can be used to encapsulate away a change of implementation in midstream.Caution: This depends on the delegate's thread-safety. When used with a vanilla
Random
, this means that its output for the same seed will vary when accessed concurrently from multiple threads, at least on JDK 7 and 8, if the calls include e.g.BaseRandom.nextLong()
,nextGaussian()
orBaseRandom.nextDouble()
. However,nextInt()
will still be transactional.- Author:
- Chris Hennick
- See Also:
- Serialized Form
-
-
Field Summary
-
Fields inherited from class io.github.pr0methean.betterrandom.prng.BaseRandom
ENTROPY_OF_DOUBLE, ENTROPY_OF_FLOAT, entropyBits, lock, randomSeeder, seed, superConstructorFinished
-
-
Constructor Summary
Constructors Constructor Description RandomWrapper()
Wraps aRandom
that is seeded using the default seeding strategy.RandomWrapper(byte[] seed)
Wraps aRandom
that is seeded with the specified seed.RandomWrapper(long seed)
Wraps aRandom
that is seeded with the specified seed.RandomWrapper(SeedGenerator seedGenerator)
Wraps aRandom
that is seeded using the provided seed generation strategy.RandomWrapper(Random wrapped)
Creates an instance wrapping the givenRandom
.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected MoreObjects.ToStringHelper
addSubclassFields(MoreObjects.ToStringHelper original)
Adds the fields that were not inherited from BaseRandom to the givenMoreObjects.ToStringHelper
for dumping.int
getNewSeedLength()
Returns the preferred length of a new byte-array seed.byte[]
getSeed()
Returns the wrapped PRNG's seed, if we know it.Random
getWrapped()
Returns the PRNG this RandomWrapper is currently wrapping.protected int
next(int bits)
Generates the next pseudorandom number.boolean
nextBoolean()
void
nextBytes(byte[] bytes)
Generates random bytes and places them into a user-supplied byte array.double
nextDoubleNoEntropyDebit()
Returns the next randomdouble
between 0.0 (inclusive) and 1.0 (exclusive), but does not debit entropy.float
nextFloat()
double
nextGaussian()
Returns the next pseudorandom, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence.int
nextInt()
int
nextInt(int bound)
protected long
nextLongNoEntropyDebit()
Returns the next randomlong
, but does not debit entropy.boolean
preferSeedWithLong()
Indicates whetherRandom.setSeed(long)
is recommended overByteArrayReseedableRandom.setSeed(byte[])
when the seed is already in the form of along
.void
setSeed(long seed)
Sets the seed of this random number generator using a single long seed, if this implementation supports that.protected void
setSeedInternal(byte[] seed)
Delegates to one ofByteArrayReseedableRandom.setSeed(byte[])
,SecureRandom.setSeed(byte[])
orRandom.setSeed(long)
.void
setWrapped(Random wrapped)
Replaces the wrapped PRNG with the given one on subsequent calls.protected boolean
supportsMultipleSeedLengths()
If true, the subclass takes responsibility for checking whether the seed is non-null and has a valid length, and should throw anIllegalArgumentException
inBaseRandom.setSeedInternal(byte[])
if not.String
toString()
boolean
usesParallelStreams()
-
Methods inherited from class io.github.pr0methean.betterrandom.prng.BaseRandom
checkLength, creditEntropyForNewSeed, debitEntropy, doubles, doubles, doubles, doubles, dump, entropyOfInt, entropyOfLong, fallbackSetSeedIfInitialized, gaussians, gaussians, getEntropyBits, getRandomSeeder, initTransientFields, internalNextGaussian, ints, ints, ints, ints, lockForNextGaussian, longs, longs, longs, longs, needsReseedingEarly, nextDouble, nextDouble, nextDouble, nextElement, nextElement, nextEnum, nextInt, nextLong, nextLong, nextLong, setRandomSeeder, setSeed, unlockForNextGaussian, withProbability, withProbabilityInternal
-
-
-
-
Constructor Detail
-
RandomWrapper
public RandomWrapper() throws SeedException
Wraps aRandom
that is seeded using the default seeding strategy.- Throws:
SeedException
- if thrown byDefaultSeedGenerator
-
RandomWrapper
public RandomWrapper(SeedGenerator seedGenerator) throws SeedException
Wraps aRandom
that is seeded using the provided seed generation strategy.- Parameters:
seedGenerator
- The seed generation strategy that will provide the seed for this PRNG- Throws:
SeedException
- if thrown byrandomSeeder
-
RandomWrapper
public RandomWrapper(byte[] seed)
Wraps aRandom
that is seeded with the specified seed.- Parameters:
seed
- seed used to initialize theRandom
; must be 8 bytes
-
RandomWrapper
public RandomWrapper(long seed)
Wraps aRandom
that is seeded with the specified seed.- Parameters:
seed
- seed used to initialize theRandom
-
-
Method Detail
-
usesParallelStreams
public boolean usesParallelStreams()
- Overrides:
usesParallelStreams
in classBaseRandom
- Returns:
- true if this PRNG creates parallel streams; false otherwise.
-
next
protected int next(int bits)
Description copied from class:BaseRandom
Generates the next pseudorandom number. Called by all other random-number-generating methods. Should not debit the entropy count, since that's done by the calling methods according to the amount they actually output (see for exampleBaseRandom.withProbability(double)
, which uses 53 random bits but outputs only one, and thus debits only 1 bit of entropy).- Specified by:
next
in classBaseRandom
-
getWrapped
public Random getWrapped()
Returns the PRNG this RandomWrapper is currently wrapping.- Returns:
- the wrapped
Random
instance
-
setWrapped
public void setWrapped(Random wrapped)
Replaces the wrapped PRNG with the given one on subsequent calls.- Parameters:
wrapped
- anRandom
instance to wrap
-
addSubclassFields
protected MoreObjects.ToStringHelper addSubclassFields(MoreObjects.ToStringHelper original)
Description copied from class:BaseRandom
Adds the fields that were not inherited from BaseRandom to the givenMoreObjects.ToStringHelper
for dumping.- Specified by:
addSubclassFields
in classBaseRandom
- Parameters:
original
- aMoreObjects.ToStringHelper
object.- Returns:
original
with the fields not inherited from BaseRandom written to it.
-
getSeed
public byte[] getSeed()
Returns the wrapped PRNG's seed, if we know it. When this RandomWrapper is wrapping a passed-inRandom
that's not aRepeatableRandom
, we won't know the seed until the nextBaseRandom.setSeed(byte[])
orsetSeed(long)
call lets us set it ourselves, and so anUnsupportedOperationException
will be thrown until then.- Specified by:
getSeed
in interfaceRepeatableRandom
- Overrides:
getSeed
in classBaseRandom
- Returns:
- The seed data used to initialize this pseudo-random number generator.
- Throws:
UnsupportedOperationException
- if this RandomWrapper doesn't know the wrapped PRNG's seed.
-
setSeed
public void setSeed(long seed)
Description copied from class:BaseRandom
Sets the seed of this random number generator using a single long seed, if this implementation supports that. If it is capable of using 64 bits or less of seed data (i.e. if{@link #getNewSeedLength()} <= {@link Long#BYTES}
), then this method shall replace the entire seed asRandom.setSeed(long)
does; otherwise, it shall either combine the input with the existing seed asSecureRandom.setSeed(long)
does, or it shall generate a new seed using theDefaultSeedGenerator
. The latter is a backward-compatibility measure and can be very slow.- Specified by:
setSeed
in interfaceJava8CompatRandom
- Overrides:
setSeed
in classBaseRandom
-
setSeedInternal
protected void setSeedInternal(byte[] seed)
Delegates to one ofByteArrayReseedableRandom.setSeed(byte[])
,SecureRandom.setSeed(byte[])
orRandom.setSeed(long)
.- Overrides:
setSeedInternal
in classBaseRandom
- Parameters:
seed
- The new seed.
-
supportsMultipleSeedLengths
protected boolean supportsMultipleSeedLengths()
Description copied from class:BaseRandom
If true, the subclass takes responsibility for checking whether the seed is non-null and has a valid length, and should throw anIllegalArgumentException
inBaseRandom.setSeedInternal(byte[])
if not.- Overrides:
supportsMultipleSeedLengths
in classBaseRandom
- Returns:
- true if this PRNG supports seed lengths other than
BaseRandom.getNewSeedLength()
; false otherwise.
-
preferSeedWithLong
public boolean preferSeedWithLong()
Description copied from interface:ByteArrayReseedableRandom
Indicates whetherRandom.setSeed(long)
is recommended overByteArrayReseedableRandom.setSeed(byte[])
when the seed is already in the form of along
.- Specified by:
preferSeedWithLong
in interfaceByteArrayReseedableRandom
- Overrides:
preferSeedWithLong
in classBaseRandom
- Returns:
- true if
Random.setSeed(long)
will tend to perform better thanByteArrayReseedableRandom.setSeed(byte[])
.
-
getNewSeedLength
public int getNewSeedLength()
Description copied from interface:ByteArrayReseedableRandom
Returns the preferred length of a new byte-array seed. "Preferred" is implementation-defined when multiple seed lengths are supported, but should probably usually mean the longest one, since the longer the seed, the more random the output.- Specified by:
getNewSeedLength
in interfaceByteArrayReseedableRandom
- Specified by:
getNewSeedLength
in classBaseRandom
- Returns:
- The desired length of a new byte-array seed.
-
nextBytes
public void nextBytes(byte[] bytes)
Description copied from class:BaseRandom
Generates random bytes and places them into a user-supplied byte array. The number of random bytes produced is equal to the length of the byte array. Reimplemented for entropy-counting purposes.- Specified by:
nextBytes
in interfaceJava8CompatRandom
- Overrides:
nextBytes
in classBaseRandom
-
nextInt
public int nextInt()
- Specified by:
nextInt
in interfaceJava8CompatRandom
- Overrides:
nextInt
in classBaseRandom
-
nextInt
public int nextInt(int bound)
- Specified by:
nextInt
in interfaceJava8CompatRandom
- Overrides:
nextInt
in classBaseRandom
-
nextLongNoEntropyDebit
protected long nextLongNoEntropyDebit()
Description copied from class:BaseRandom
Returns the next randomlong
, but does not debit entropy.- Overrides:
nextLongNoEntropyDebit
in classBaseRandom
- Returns:
- a pseudorandom
long
with all possible values equally likely.
-
nextBoolean
public boolean nextBoolean()
- Specified by:
nextBoolean
in interfaceJava8CompatRandom
- Overrides:
nextBoolean
in classBaseRandom
-
nextFloat
public float nextFloat()
- Specified by:
nextFloat
in interfaceJava8CompatRandom
- Overrides:
nextFloat
in classBaseRandom
-
nextDoubleNoEntropyDebit
public double nextDoubleNoEntropyDebit()
Description copied from class:BaseRandom
Returns the next randomdouble
between 0.0 (inclusive) and 1.0 (exclusive), but does not debit entropy.- Overrides:
nextDoubleNoEntropyDebit
in classBaseRandom
- Returns:
- a pseudorandom
double
.
-
nextGaussian
public double nextGaussian()
Description copied from class:BaseRandom
Returns the next pseudorandom, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0 from this random number generator's sequence. Unlike the one inRandom
, this implementation is lockless.- Specified by:
nextGaussian
in interfaceJava8CompatRandom
- Overrides:
nextGaussian
in classBaseRandom
-
-