Added RandomValue generators
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
package com.r35157.libs.random;
|
||||
|
||||
/**
|
||||
* This interface provides a way to generate random integers.
|
||||
*/
|
||||
public interface RandomValueGeneratorInt {
|
||||
/**
|
||||
* Returns a random integer in the full range (min -2<sup>31</sup>. to max 2<sup>31</sup>-1)
|
||||
*
|
||||
* @return a random integer in full range
|
||||
*/
|
||||
int getSomeInt();
|
||||
|
||||
/**
|
||||
* Returns a random integer in the range provided by the parameters. Both parameters are included in the range and
|
||||
* {@code minInclusive} must be less than {@code maxInclusive}.
|
||||
*
|
||||
* @return a random integer in the provided range
|
||||
*/
|
||||
int getSomeInt(int minInclusive, int maxInclusive);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.r35157.libs.random;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface RandomValueGeneratorString {
|
||||
/**
|
||||
* Generate a random Alpha Numeric String of exactly the length given as the parameter.
|
||||
*
|
||||
* @param length Length of generated String - cannot be negative
|
||||
* @return A non-null random String of the length given
|
||||
* @throws IllegalArgumentException If length is negative
|
||||
*/
|
||||
@NotNull String getSomeStringAlphaNumericOnly(int length) throws IllegalArgumentException;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.r35157.libs.random.impl.ref;
|
||||
|
||||
import com.r35157.libs.random.RandomValueGeneratorInt;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static java.lang.Integer.MAX_VALUE;
|
||||
import static java.lang.Integer.MIN_VALUE;
|
||||
|
||||
public class RandomValueGeneratorIntImpl implements RandomValueGeneratorInt {
|
||||
@Override
|
||||
public int getSomeInt() {
|
||||
// Default: use the full int range
|
||||
return getSomeInt(MIN_VALUE, MAX_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSomeInt(int minInclusive, int maxInclusive) {
|
||||
if (minInclusive > maxInclusive) {
|
||||
String errorMessage = String.format("'minInclusive' (%d) must be less than or equal to 'maxInclusive' (%d)",
|
||||
minInclusive, maxInclusive);
|
||||
throw new IllegalArgumentException(errorMessage);
|
||||
}
|
||||
|
||||
if (minInclusive == maxInclusive) {
|
||||
// Edge case: only one possible value
|
||||
return minInclusive;
|
||||
}
|
||||
|
||||
// Fast path: full int range – ThreadLocalRandom.nextInt() already covers it
|
||||
if (minInclusive == MIN_VALUE && maxInclusive == MAX_VALUE) {
|
||||
return ThreadLocalRandom.current().nextInt();
|
||||
}
|
||||
|
||||
// Use long to avoid overflow when calculating range size
|
||||
long bound = ((long) maxInclusive - (long) minInclusive) + 1L;
|
||||
|
||||
if (bound <= Integer.MAX_VALUE) {
|
||||
// Normal case: the range fits in an int
|
||||
// nextInt(bound) gives a uniform value in [0, bound],
|
||||
// then shift it into the target range by adding minInclusive
|
||||
return minInclusive + ThreadLocalRandom.current().nextInt((int) bound);
|
||||
} else {
|
||||
// Rare case: the range is larger than Integer.MAX_VALUE
|
||||
// (e.g. almost the full int space). Use rejection sampling:
|
||||
// draw values until one falls within the desired interval.
|
||||
int r;
|
||||
do {
|
||||
r = ThreadLocalRandom.current().nextInt();
|
||||
} while (r < minInclusive || r > maxInclusive);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.r35157.libs.random.impl.ref;
|
||||
|
||||
import com.r35157.libs.random.RandomValueGeneratorInt;
|
||||
import com.r35157.libs.random.RandomValueGeneratorString;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class RandomValueGeneratorStringImpl implements RandomValueGeneratorString {
|
||||
public RandomValueGeneratorStringImpl(@NotNull RandomValueGeneratorInt rvgi) {
|
||||
Objects.requireNonNull(rvgi, "Cannot initialize with <null> RandomValueGeneratorInt!");
|
||||
this.rvgi = rvgi;
|
||||
}
|
||||
|
||||
public @NotNull String getSomeStringAlphaNumericOnly(int length) throws IllegalArgumentException {
|
||||
if(length < 0) {
|
||||
throw new IllegalArgumentException("Cannot generate random Strings of size " + length + "!");
|
||||
}
|
||||
|
||||
// ASCII Range size
|
||||
// Numeric 48-57 10
|
||||
// Alpha upper 65-90 26
|
||||
// Alpha lower 97-122 26
|
||||
int totalNumberOfCandidates = 10 + 26 + 26;
|
||||
|
||||
StringBuilder buffer = new StringBuilder(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
int randomInt = rvgi.getSomeInt(0, totalNumberOfCandidates - 1);
|
||||
int asciiIndex = convertRandomIndexToASCIIIndex(randomInt);
|
||||
|
||||
buffer.append((char) asciiIndex);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private static int convertRandomIndexToASCIIIndex(int randomIndex) {
|
||||
// RandomIndex 0... ...9 - 10... ...35 - 36... ... 61
|
||||
// ASCII values: 48...<numeric>...57 - 65...<alpha upper>...90 - 97...<alpha lower>...122
|
||||
int asciiIndex;
|
||||
|
||||
if(randomIndex >= 36) {
|
||||
asciiIndex = 97 + (randomIndex - 36);
|
||||
} else if(randomIndex >= 10) {
|
||||
asciiIndex = 65 + (randomIndex - 10);
|
||||
} else {
|
||||
asciiIndex = 48 + randomIndex;
|
||||
}
|
||||
|
||||
return asciiIndex;
|
||||
}
|
||||
|
||||
private RandomValueGeneratorInt rvgi;
|
||||
}
|
||||
Reference in New Issue
Block a user