diff --git a/java-numbers-2/pom.xml b/java-numbers-2/pom.xml
index ba40ef0a38..f5f10d9364 100644
--- a/java-numbers-2/pom.xml
+++ b/java-numbers-2/pom.xml
@@ -21,6 +21,11 @@
jmh-generator-annprocess
${jmh-generator.version}
+
+ it.unimi.dsi
+ dsiutils
+ 2.6.0
+
diff --git a/java-numbers-2/src/main/java/com/baeldung/randomnumbers/RandomNumbersGenerator.java b/java-numbers-2/src/main/java/com/baeldung/randomnumbers/RandomNumbersGenerator.java
new file mode 100644
index 0000000000..84cd3eecb6
--- /dev/null
+++ b/java-numbers-2/src/main/java/com/baeldung/randomnumbers/RandomNumbersGenerator.java
@@ -0,0 +1,91 @@
+package com.baeldung.randomnumbers;
+
+import java.security.SecureRandom;
+import java.util.Random;
+import java.util.SplittableRandom;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.stream.IntStream;
+
+import org.apache.commons.math3.random.RandomDataGenerator;
+
+import it.unimi.dsi.util.XoRoShiRo128PlusRandom;
+
+public class RandomNumbersGenerator {
+
+ public Integer generateRandomWithMathRandom(int max, int min) {
+ return (int) ((Math.random() * (max - min)) + min);
+ }
+
+ public Integer generateRandomWithNextInt() {
+ Random random = new Random();
+ int randomWithNextInt = random.nextInt();
+ return randomWithNextInt;
+ }
+
+ public Integer generateRandomWithNextIntWithinARange(int min, int max) {
+ Random random = new Random();
+ int randomWintNextIntWithinARange = random.nextInt(max - min) + min;
+ return randomWintNextIntWithinARange;
+ }
+
+ public IntStream generateRandomUnlimitedIntStream() {
+ Random random = new Random();
+ IntStream unlimitedIntStream = random.ints();
+ return unlimitedIntStream;
+ }
+
+ public IntStream generateRandomLimitedIntStream(long streamSize) {
+ Random random = new Random();
+ IntStream limitedIntStream = random.ints(streamSize);
+ return limitedIntStream;
+ }
+
+ public IntStream generateRandomLimitedIntStreamWithinARange(int min, int max, long streamSize) {
+ Random random = new Random();
+ IntStream limitedIntStreamWithinARange = random.ints(streamSize, min, max);
+ return limitedIntStreamWithinARange;
+ }
+
+ public Integer generateRandomWithThreadLocalRandom() {
+ int randomWithThreadLocalRandom = ThreadLocalRandom.current()
+ .nextInt();
+ return randomWithThreadLocalRandom;
+ }
+
+ public Integer generateRandomWithThreadLocalRandomInARange(int min, int max) {
+ int randomWithThreadLocalRandomInARange = ThreadLocalRandom.current()
+ .nextInt(min, max);
+ return randomWithThreadLocalRandomInARange;
+ }
+
+ public Integer generateRandomWithThreadLocalRandomFromZero(int max) {
+ int randomWithThreadLocalRandomFromZero = ThreadLocalRandom.current()
+ .nextInt(max);
+ return randomWithThreadLocalRandomFromZero;
+ }
+
+ public Integer generateRandomWithSplittableRandom(int min, int max) {
+ SplittableRandom splittableRandom = new SplittableRandom();
+ int randomWithSplittableRandom = splittableRandom.nextInt(min, max);
+ return randomWithSplittableRandom;
+ }
+
+ public Integer generateRandomWithSecureRandom() {
+ SecureRandom secureRandom = new SecureRandom();
+ int randomWithSecureRandom = secureRandom.nextInt();
+ return randomWithSecureRandom;
+ }
+
+ public Integer generateRandomWithRandomDataGenerator(int min, int max) {
+ RandomDataGenerator randomDataGenerator = new RandomDataGenerator();
+ int randomWithRandomDataGenerator = randomDataGenerator.nextInt(min, max);
+ return randomWithRandomDataGenerator;
+ }
+
+ public Integer generateRandomWithXoRoShiRo128PlusRandom(int min, int max) {
+ XoRoShiRo128PlusRandom xoroRandom = new XoRoShiRo128PlusRandom();
+ int randomWithXoRoShiRo128PlusRandom = xoroRandom.nextInt(max - min) + min;
+ return randomWithXoRoShiRo128PlusRandom;
+ }
+
+}
diff --git a/java-numbers-2/src/test/java/com/baeldung/randomnumbers/RandomNumbersGeneratorUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/randomnumbers/RandomNumbersGeneratorUnitTest.java
new file mode 100644
index 0000000000..31d334f8b8
--- /dev/null
+++ b/java-numbers-2/src/test/java/com/baeldung/randomnumbers/RandomNumbersGeneratorUnitTest.java
@@ -0,0 +1,137 @@
+package com.baeldung.randomnumbers;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.stream.IntStream;
+
+import org.junit.Test;
+
+public class RandomNumbersGeneratorUnitTest {
+
+ private static final int MIN_RANGE = 1;
+ private static final int MAX_RANGE = 10;
+ private static final int ITERATIONS = 50;
+ private static final long STREAM_SIZE = 50;
+
+ @Test
+ public void whenGenerateRandomWithMathRandom_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ for (int i = 0; i < ITERATIONS; i++) {
+ int randomNumer = generator.generateRandomWithMathRandom(MIN_RANGE, MAX_RANGE);
+ assertTrue(isInRange(randomNumer, Integer.MIN_VALUE, Integer.MAX_VALUE));
+ }
+ }
+
+ @Test
+ public void whenGenerateRandomWithNextInt_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ for (int i = 0; i < ITERATIONS; i++) {
+ int randomNumber = generator.generateRandomWithNextInt();
+ assertTrue(isInRange(randomNumber, Integer.MIN_VALUE, Integer.MAX_VALUE));
+ }
+ }
+
+ @Test
+ public void whenGenerateRandomWithNextIntWithinARange_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ for (int i = 0; i < ITERATIONS; i++) {
+ int randomNumber = generator.generateRandomWithNextIntWithinARange(MIN_RANGE, MAX_RANGE);
+ assertTrue(isInRange(randomNumber, MIN_RANGE, MAX_RANGE));
+ }
+ }
+
+ @Test
+ public void whenGenerateRandomUnlimitedIntStream_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ IntStream stream = generator.generateRandomUnlimitedIntStream();
+ assertNotNull(stream);
+ Integer randomNumber = stream.findFirst()
+ .getAsInt();
+ assertNotNull(randomNumber);
+ assertTrue(isInRange(randomNumber, Integer.MIN_VALUE, Integer.MAX_VALUE));
+ }
+
+ @Test
+ public void whenGenerateRandomLimitedIntStream_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ generator.generateRandomLimitedIntStream(STREAM_SIZE)
+ .forEach(randomNumber -> assertTrue(isInRange(randomNumber, Integer.MIN_VALUE, Integer.MAX_VALUE)));
+ }
+
+ @Test
+ public void whenGenerateRandomLimitedIntStreamWithinARange_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ generator.generateRandomLimitedIntStreamWithinARange(MIN_RANGE, MAX_RANGE, STREAM_SIZE)
+ .forEach(randomNumber -> assertTrue(isInRange(randomNumber, MIN_RANGE, MAX_RANGE)));
+ }
+
+ @Test
+ public void whenGenerateRandomWithThreadLocalRandom_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ for (int i = 0; i < ITERATIONS; i++) {
+ int randomNumber = generator.generateRandomWithThreadLocalRandom();
+ assertTrue(isInRange(randomNumber, Integer.MIN_VALUE, Integer.MAX_VALUE));
+ }
+ }
+
+ @Test
+ public void whenGenerateRandomWithThreadLocalRandomInARange_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ for (int i = 0; i < ITERATIONS; i++) {
+ int randomNumber = generator.generateRandomWithThreadLocalRandomInARange(MIN_RANGE, MAX_RANGE);
+ assertTrue(isInRange(randomNumber, MIN_RANGE, MAX_RANGE));
+ }
+ }
+
+ @Test
+ public void whenGenerateRandomWithThreadLocalRandomFromZero_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ for (int i = 0; i < ITERATIONS; i++) {
+ int randomNumber = generator.generateRandomWithThreadLocalRandomFromZero(MAX_RANGE);
+ assertTrue(isInRange(randomNumber, 0, MAX_RANGE));
+ }
+ }
+
+ @Test
+ public void whenGenerateRandomWithSplittableRandom_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ for (int i = 0; i < ITERATIONS; i++) {
+ int randomNumber = generator.generateRandomWithSplittableRandom(MIN_RANGE, MAX_RANGE);
+ assertTrue(isInRange(randomNumber, MIN_RANGE, MAX_RANGE));
+ }
+ }
+
+ @Test
+ public void whenGenerateRandomWithSecureRandom_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ for (int i = 0; i < ITERATIONS; i++) {
+ int randomNumber = generator.generateRandomWithSecureRandom();
+ assertTrue(isInRange(randomNumber, Integer.MIN_VALUE, Integer.MAX_VALUE));
+ }
+ }
+
+ @Test
+ public void whenGenerateRandomWithRandomDataGenerator_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ for (int i = 0; i < ITERATIONS; i++) {
+ int randomNumber = generator.generateRandomWithRandomDataGenerator(MIN_RANGE, MAX_RANGE);
+ // RandomDataGenerator top is inclusive
+ assertTrue(isInRange(randomNumber, MIN_RANGE, MAX_RANGE + 1));
+ }
+ }
+
+ @Test
+ public void whenGenerateRandomWithXoRoShiRo128PlusRandom_returnsSuccessfully() {
+ RandomNumbersGenerator generator = new RandomNumbersGenerator();
+ for (int i = 0; i < ITERATIONS; i++) {
+ int randomNumber = generator.generateRandomWithXoRoShiRo128PlusRandom(MIN_RANGE, MAX_RANGE);
+ assertTrue(isInRange(randomNumber, MIN_RANGE, MAX_RANGE));
+ }
+ }
+
+ private boolean isInRange(int number, int min, int max) {
+ return min <= number && number < max;
+ }
+
+}