This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-lang.git
The following commit(s) were added to refs/heads/master by this push: new 2978cb6 DMI: Random object created and used only once (DMI_RANDOM_USED_ONLY_ONCE); Better multi-threaded behavior. 2978cb6 is described below commit 2978cb6cf05379fd42374eb5a235be84e021f247 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Sun Apr 18 19:21:44 2021 -0400 DMI: Random object created and used only once (DMI_RANDOM_USED_ONLY_ONCE); Better multi-threaded behavior. Thank you SpotBugs. Sort methods. --- src/changes/changes.xml | 1 + .../java/org/apache/commons/lang3/ArrayUtils.java | 23 +- .../apache/commons/lang3/RandomStringUtils.java | 408 ++++++++++----------- .../java/org/apache/commons/lang3/RandomUtils.java | 149 ++++---- 4 files changed, 292 insertions(+), 289 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 472eff5..f508683 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -49,6 +49,7 @@ The <action> type attribute can be add,update,fix,remove. <!-- FIX --> <action issue="LANG-1645" type="fix" dev="aherbert" due-to="Alex Herbert">NumberUtils.createNumber() to recognize hex integers prefixed with +.</action> <action issue="LANG-1646" type="fix" dev="aherbert" due-to="Alex Herbert">NumberUtils.createNumber() to return requested floating point type for zero.</action> + <action type="fix" dev="ggregory" due-to="SpotBugs, Gary Gregory">DMI: Random object created and used only once (DMI_RANDOM_USED_ONLY_ONCE); Better multi-threaded behavior.</action> <!-- ADD --> <action type="add" dev="ggregory" due-to="Gary Gregory">Add EnumUtils.getEnumSystemProperty(...).</action> <action type="add" dev="ggregory" due-to="Gary Gregory">Add TriConsumer.</action> diff --git a/src/main/java/org/apache/commons/lang3/ArrayUtils.java b/src/main/java/org/apache/commons/lang3/ArrayUtils.java index 33acf3e..9f115fe 100644 --- a/src/main/java/org/apache/commons/lang3/ArrayUtils.java +++ b/src/main/java/org/apache/commons/lang3/ArrayUtils.java @@ -26,6 +26,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -4644,6 +4645,10 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd return array; } + private static ThreadLocalRandom random() { + return ThreadLocalRandom.current(); + } + /** * <p>Removes the element at the specified position from the specified array. * All subsequent elements are shifted to the left (subtracts one from @@ -7659,7 +7664,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd * @since 3.6 */ public static void shuffle(final boolean[] array) { - shuffle(array, new Random()); + shuffle(array, random()); } /** @@ -7684,7 +7689,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd * @since 3.6 */ public static void shuffle(final byte[] array) { - shuffle(array, new Random()); + shuffle(array, random()); } /** @@ -7709,7 +7714,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd * @since 3.6 */ public static void shuffle(final char[] array) { - shuffle(array, new Random()); + shuffle(array, random()); } /** @@ -7734,7 +7739,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd * @since 3.6 */ public static void shuffle(final double[] array) { - shuffle(array, new Random()); + shuffle(array, random()); } /** @@ -7759,7 +7764,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd * @since 3.6 */ public static void shuffle(final float[] array) { - shuffle(array, new Random()); + shuffle(array, random()); } /** @@ -7784,7 +7789,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd * @since 3.6 */ public static void shuffle(final int[] array) { - shuffle(array, new Random()); + shuffle(array, random()); } /** @@ -7809,7 +7814,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd * @since 3.6 */ public static void shuffle(final long[] array) { - shuffle(array, new Random()); + shuffle(array, random()); } /** @@ -7834,7 +7839,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd * @since 3.6 */ public static void shuffle(final Object[] array) { - shuffle(array, new Random()); + shuffle(array, random()); } /** @@ -7859,7 +7864,7 @@ public static int indexOf(final int[] array, final int valueToFind, int startInd * @since 3.6 */ public static void shuffle(final short[] array) { - shuffle(array, new Random()); + shuffle(array, random()); } /** diff --git a/src/main/java/org/apache/commons/lang3/RandomStringUtils.java b/src/main/java/org/apache/commons/lang3/RandomStringUtils.java index 6f0242a..835c8a3 100644 --- a/src/main/java/org/apache/commons/lang3/RandomStringUtils.java +++ b/src/main/java/org/apache/commons/lang3/RandomStringUtils.java @@ -17,6 +17,7 @@ package org.apache.commons.lang3; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; /** * <p>Generates random {@code String}s.</p> @@ -48,22 +49,8 @@ import java.util.Random; */ public class RandomStringUtils { - /** - * <p>Random object used by random method. This has to be not local - * to the random method so as to not return the same value in the - * same millisecond.</p> - */ - private static final Random RANDOM = new Random(); - - /** - * <p>{@code RandomStringUtils} instances should NOT be constructed in - * standard programming. Instead, the class should be used as - * {@code RandomStringUtils.random(5);}.</p> - * - * <p>This constructor is public to permit tools that require a JavaBean instance - * to operate.</p> - */ - public RandomStringUtils() { + private static ThreadLocalRandom random() { + return ThreadLocalRandom.current(); } // Random @@ -85,196 +72,37 @@ public class RandomStringUtils { * <p>Creates a random string whose length is the number of characters * specified.</p> * - * <p>Characters will be chosen from the set of characters whose - * ASCII value is between {@code 32} and {@code 126} (inclusive).</p> - * - * @param count the length of random string to create - * @return the random string - */ - public static String randomAscii(final int count) { - return random(count, 32, 127, false, false); - } - - /** - * <p>Creates a random string whose length is between the inclusive minimum and - * the exclusive maximum.</p> - * - * <p>Characters will be chosen from the set of characters whose - * ASCII value is between {@code 32} and {@code 126} (inclusive).</p> - * - * @param minLengthInclusive the inclusive minimum length of the string to generate - * @param maxLengthExclusive the exclusive maximum length of the string to generate - * @return the random string - * @since 3.5 - */ - public static String randomAscii(final int minLengthInclusive, final int maxLengthExclusive) { - return randomAscii(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); - } - - /** - * <p>Creates a random string whose length is the number of characters - * specified.</p> - * - * <p>Characters will be chosen from the set of Latin alphabetic - * characters (a-z, A-Z).</p> - * - * @param count the length of random string to create - * @return the random string - */ - public static String randomAlphabetic(final int count) { - return random(count, true, false); - } - - /** - * <p>Creates a random string whose length is between the inclusive minimum and - * the exclusive maximum.</p> - * - * <p>Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).</p> - * - * @param minLengthInclusive the inclusive minimum length of the string to generate - * @param maxLengthExclusive the exclusive maximum length of the string to generate - * @return the random string - * @since 3.5 - */ - public static String randomAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) { - return randomAlphabetic(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); - } - - /** - * <p>Creates a random string whose length is the number of characters - * specified.</p> - * - * <p>Characters will be chosen from the set of Latin alphabetic - * characters (a-z, A-Z) and the digits 0-9.</p> - * - * @param count the length of random string to create - * @return the random string - */ - public static String randomAlphanumeric(final int count) { - return random(count, true, true); - } - - /** - * <p>Creates a random string whose length is between the inclusive minimum and - * the exclusive maximum.</p> - * - * <p>Characters will be chosen from the set of Latin alphabetic - * characters (a-z, A-Z) and the digits 0-9.</p> - * - * @param minLengthInclusive the inclusive minimum length of the string to generate - * @param maxLengthExclusive the exclusive maximum length of the string to generate - * @return the random string - * @since 3.5 - */ - public static String randomAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) { - return randomAlphanumeric(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); - } - - /** - * <p>Creates a random string whose length is the number of characters specified.</p> - * - * <p>Characters will be chosen from the set of characters which match the POSIX [:graph:] - * regular expression character class. This class contains all visible ASCII characters - * (i.e. anything except spaces and control characters).</p> - * - * @param count the length of random string to create - * @return the random string - * @since 3.5 - */ - public static String randomGraph(final int count) { - return random(count, 33, 126, false, false); - } - - /** - * <p>Creates a random string whose length is between the inclusive minimum and - * the exclusive maximum.</p> - * - * <p>Characters will be chosen from the set of \p{Graph} characters.</p> - * - * @param minLengthInclusive the inclusive minimum length of the string to generate - * @param maxLengthExclusive the exclusive maximum length of the string to generate - * @return the random string - * @since 3.5 - */ - public static String randomGraph(final int minLengthInclusive, final int maxLengthExclusive) { - return randomGraph(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); - } - - /** - * <p>Creates a random string whose length is the number of characters - * specified.</p> - * - * <p>Characters will be chosen from the set of numeric - * characters.</p> - * - * @param count the length of random string to create - * @return the random string - */ - public static String randomNumeric(final int count) { - return random(count, false, true); - } - - /** - * <p>Creates a random string whose length is between the inclusive minimum and - * the exclusive maximum.</p> - * - * <p>Characters will be chosen from the set of \p{Digit} characters.</p> - * - * @param minLengthInclusive the inclusive minimum length of the string to generate - * @param maxLengthExclusive the exclusive maximum length of the string to generate - * @return the random string - * @since 3.5 - */ - public static String randomNumeric(final int minLengthInclusive, final int maxLengthExclusive) { - return randomNumeric(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); - } - - /** - * <p>Creates a random string whose length is the number of characters specified.</p> - * - * <p>Characters will be chosen from the set of characters which match the POSIX [:print:] - * regular expression character class. This class includes all visible ASCII characters and spaces - * (i.e. anything except control characters).</p> + * <p>Characters will be chosen from the set of alpha-numeric + * characters as indicated by the arguments.</p> * * @param count the length of random string to create + * @param letters if {@code true}, generated string may include + * alphabetic characters + * @param numbers if {@code true}, generated string may include + * numeric characters * @return the random string - * @since 3.5 - */ - public static String randomPrint(final int count) { - return random(count, 32, 126, false, false); - } - - /** - * <p>Creates a random string whose length is between the inclusive minimum and - * the exclusive maximum.</p> - * - * <p>Characters will be chosen from the set of \p{Print} characters.</p> - * - * @param minLengthInclusive the inclusive minimum length of the string to generate - * @param maxLengthExclusive the exclusive maximum length of the string to generate - * @return the random string - * @since 3.5 */ - public static String randomPrint(final int minLengthInclusive, final int maxLengthExclusive) { - return randomPrint(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + public static String random(final int count, final boolean letters, final boolean numbers) { + return random(count, 0, 0, letters, numbers); } /** * <p>Creates a random string whose length is the number of characters * specified.</p> * - * <p>Characters will be chosen from the set of alpha-numeric - * characters as indicated by the arguments.</p> + * <p>Characters will be chosen from the set of characters specified.</p> * * @param count the length of random string to create - * @param letters if {@code true}, generated string may include - * alphabetic characters - * @param numbers if {@code true}, generated string may include - * numeric characters + * @param chars the character array containing the set of characters to use, + * may be null * @return the random string + * @throws IllegalArgumentException if {@code count} < 0. */ - public static String random(final int count, final boolean letters, final boolean numbers) { - return random(count, 0, 0, letters, numbers); + public static String random(final int count, final char... chars) { + if (chars == null) { + return random(count, 0, 0, false, false, null, random()); + } + return random(count, 0, chars.length, false, false, chars, random()); } /** @@ -294,7 +122,7 @@ public class RandomStringUtils { * @return the random string */ public static String random(final int count, final int start, final int end, final boolean letters, final boolean numbers) { - return random(count, start, end, letters, numbers, null, RANDOM); + return random(count, start, end, letters, numbers, null, random()); } /** @@ -320,7 +148,7 @@ public class RandomStringUtils { * {@code (end - start) + 1} characters in the set array. */ public static String random(final int count, final int start, final int end, final boolean letters, final boolean numbers, final char... chars) { - return random(count, start, end, letters, numbers, chars, RANDOM); + return random(count, start, end, letters, numbers, chars, random()); } /** @@ -434,7 +262,6 @@ public class RandomStringUtils { return builder.toString(); } - /** * <p>Creates a random string whose length is the number of characters * specified.</p> @@ -451,7 +278,7 @@ public class RandomStringUtils { */ public static String random(final int count, final String chars) { if (chars == null) { - return random(count, 0, 0, false, false, null, RANDOM); + return random(count, 0, 0, false, false, null, random()); } return random(count, chars.toCharArray()); } @@ -460,19 +287,190 @@ public class RandomStringUtils { * <p>Creates a random string whose length is the number of characters * specified.</p> * - * <p>Characters will be chosen from the set of characters specified.</p> + * <p>Characters will be chosen from the set of Latin alphabetic + * characters (a-z, A-Z).</p> * * @param count the length of random string to create - * @param chars the character array containing the set of characters to use, - * may be null * @return the random string - * @throws IllegalArgumentException if {@code count} < 0. */ - public static String random(final int count, final char... chars) { - if (chars == null) { - return random(count, 0, 0, false, false, null, RANDOM); - } - return random(count, 0, chars.length, false, false, chars, RANDOM); + public static String randomAlphabetic(final int count) { + return random(count, true, false); + } + + /** + * <p>Creates a random string whose length is between the inclusive minimum and + * the exclusive maximum.</p> + * + * <p>Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z).</p> + * + * @param minLengthInclusive the inclusive minimum length of the string to generate + * @param maxLengthExclusive the exclusive maximum length of the string to generate + * @return the random string + * @since 3.5 + */ + public static String randomAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) { + return randomAlphabetic(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + } + + /** + * <p>Creates a random string whose length is the number of characters + * specified.</p> + * + * <p>Characters will be chosen from the set of Latin alphabetic + * characters (a-z, A-Z) and the digits 0-9.</p> + * + * @param count the length of random string to create + * @return the random string + */ + public static String randomAlphanumeric(final int count) { + return random(count, true, true); + } + + /** + * <p>Creates a random string whose length is between the inclusive minimum and + * the exclusive maximum.</p> + * + * <p>Characters will be chosen from the set of Latin alphabetic + * characters (a-z, A-Z) and the digits 0-9.</p> + * + * @param minLengthInclusive the inclusive minimum length of the string to generate + * @param maxLengthExclusive the exclusive maximum length of the string to generate + * @return the random string + * @since 3.5 + */ + public static String randomAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) { + return randomAlphanumeric(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + } + + /** + * <p>Creates a random string whose length is the number of characters + * specified.</p> + * + * <p>Characters will be chosen from the set of characters whose + * ASCII value is between {@code 32} and {@code 126} (inclusive).</p> + * + * @param count the length of random string to create + * @return the random string + */ + public static String randomAscii(final int count) { + return random(count, 32, 127, false, false); + } + + /** + * <p>Creates a random string whose length is between the inclusive minimum and + * the exclusive maximum.</p> + * + * <p>Characters will be chosen from the set of characters whose + * ASCII value is between {@code 32} and {@code 126} (inclusive).</p> + * + * @param minLengthInclusive the inclusive minimum length of the string to generate + * @param maxLengthExclusive the exclusive maximum length of the string to generate + * @return the random string + * @since 3.5 + */ + public static String randomAscii(final int minLengthInclusive, final int maxLengthExclusive) { + return randomAscii(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + } + + /** + * <p>Creates a random string whose length is the number of characters specified.</p> + * + * <p>Characters will be chosen from the set of characters which match the POSIX [:graph:] + * regular expression character class. This class contains all visible ASCII characters + * (i.e. anything except spaces and control characters).</p> + * + * @param count the length of random string to create + * @return the random string + * @since 3.5 + */ + public static String randomGraph(final int count) { + return random(count, 33, 126, false, false); + } + + /** + * <p>Creates a random string whose length is between the inclusive minimum and + * the exclusive maximum.</p> + * + * <p>Characters will be chosen from the set of \p{Graph} characters.</p> + * + * @param minLengthInclusive the inclusive minimum length of the string to generate + * @param maxLengthExclusive the exclusive maximum length of the string to generate + * @return the random string + * @since 3.5 + */ + public static String randomGraph(final int minLengthInclusive, final int maxLengthExclusive) { + return randomGraph(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + } + + /** + * <p>Creates a random string whose length is the number of characters + * specified.</p> + * + * <p>Characters will be chosen from the set of numeric + * characters.</p> + * + * @param count the length of random string to create + * @return the random string + */ + public static String randomNumeric(final int count) { + return random(count, false, true); + } + + /** + * <p>Creates a random string whose length is between the inclusive minimum and + * the exclusive maximum.</p> + * + * <p>Characters will be chosen from the set of \p{Digit} characters.</p> + * + * @param minLengthInclusive the inclusive minimum length of the string to generate + * @param maxLengthExclusive the exclusive maximum length of the string to generate + * @return the random string + * @since 3.5 + */ + public static String randomNumeric(final int minLengthInclusive, final int maxLengthExclusive) { + return randomNumeric(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + } + + /** + * <p>Creates a random string whose length is the number of characters specified.</p> + * + * <p>Characters will be chosen from the set of characters which match the POSIX [:print:] + * regular expression character class. This class includes all visible ASCII characters and spaces + * (i.e. anything except control characters).</p> + * + * @param count the length of random string to create + * @return the random string + * @since 3.5 + */ + public static String randomPrint(final int count) { + return random(count, 32, 126, false, false); + } + + + /** + * <p>Creates a random string whose length is between the inclusive minimum and + * the exclusive maximum.</p> + * + * <p>Characters will be chosen from the set of \p{Print} characters.</p> + * + * @param minLengthInclusive the inclusive minimum length of the string to generate + * @param maxLengthExclusive the exclusive maximum length of the string to generate + * @return the random string + * @since 3.5 + */ + public static String randomPrint(final int minLengthInclusive, final int maxLengthExclusive) { + return randomPrint(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + } + + /** + * <p>{@code RandomStringUtils} instances should NOT be constructed in + * standard programming. Instead, the class should be used as + * {@code RandomStringUtils.random(5);}.</p> + * + * <p>This constructor is public to permit tools that require a JavaBean instance + * to operate.</p> + */ + public RandomStringUtils() { } } diff --git a/src/main/java/org/apache/commons/lang3/RandomUtils.java b/src/main/java/org/apache/commons/lang3/RandomUtils.java index 6f963d1..38fa8dc 100644 --- a/src/main/java/org/apache/commons/lang3/RandomUtils.java +++ b/src/main/java/org/apache/commons/lang3/RandomUtils.java @@ -17,6 +17,7 @@ package org.apache.commons.lang3; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; /** * <p>Utility library that supplements the standard {@link Random} class.</p> @@ -34,27 +35,6 @@ import java.util.Random; public class RandomUtils { /** - * Random object used by random method. This has to be not local to the - * random method so as to not return the same value in the same millisecond. - */ - private static final Random RANDOM = new Random(); - - /** - * <p> - * {@code RandomUtils} instances should NOT be constructed in standard - * programming. Instead, the class should be used as - * {@code RandomUtils.nextBytes(5);}. - * </p> - * - * <p> - * This constructor is public to permit tools that require a JavaBean - * instance to operate. - * </p> - */ - public RandomUtils() { - } - - /** * <p> * Returns a random boolean value * </p> @@ -63,7 +43,7 @@ public class RandomUtils { * @since 3.5 */ public static boolean nextBoolean() { - return RANDOM.nextBoolean(); + return random().nextBoolean(); } /** @@ -80,13 +60,24 @@ public class RandomUtils { Validate.isTrue(count >= 0, "Count cannot be negative."); final byte[] result = new byte[count]; - RANDOM.nextBytes(result); + random().nextBytes(result); return result; } /** + * <p> Returns a random double within 0 - Double.MAX_VALUE </p> + * + * @return the random double + * @see #nextDouble(double, double) + * @since 3.5 + */ + public static double nextDouble() { + return nextDouble(0, Double.MAX_VALUE); + } + + /** * <p> - * Returns a random integer within the specified range. + * Returns a random double within the specified range. * </p> * * @param startInclusive @@ -96,9 +87,9 @@ public class RandomUtils { * @throws IllegalArgumentException * if {@code startInclusive > endExclusive} or if * {@code startInclusive} is negative - * @return the random integer + * @return the random double */ - public static int nextInt(final int startInclusive, final int endExclusive) { + public static double nextDouble(final double startInclusive, final double endExclusive) { Validate.isTrue(endExclusive >= startInclusive, "Start value must be smaller or equal to end value."); Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative."); @@ -107,7 +98,44 @@ public class RandomUtils { return startInclusive; } - return startInclusive + RANDOM.nextInt(endExclusive - startInclusive); + return startInclusive + ((endExclusive - startInclusive) * random().nextDouble()); + } + + /** + * <p> Returns a random float within 0 - Float.MAX_VALUE </p> + * + * @return the random float + * @see #nextFloat(float, float) + * @since 3.5 + */ + public static float nextFloat() { + return nextFloat(0, Float.MAX_VALUE); + } + + /** + * <p> + * Returns a random float within the specified range. + * </p> + * + * @param startInclusive + * the smallest value that can be returned, must be non-negative + * @param endExclusive + * the upper bound (not included) + * @throws IllegalArgumentException + * if {@code startInclusive > endExclusive} or if + * {@code startInclusive} is negative + * @return the random float + */ + public static float nextFloat(final float startInclusive, final float endExclusive) { + Validate.isTrue(endExclusive >= startInclusive, + "Start value must be smaller or equal to end value."); + Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative."); + + if (startInclusive == endExclusive) { + return startInclusive; + } + + return startInclusive + ((endExclusive - startInclusive) * random().nextFloat()); } /** @@ -123,7 +151,7 @@ public class RandomUtils { /** * <p> - * Returns a random long within the specified range. + * Returns a random integer within the specified range. * </p> * * @param startInclusive @@ -133,9 +161,9 @@ public class RandomUtils { * @throws IllegalArgumentException * if {@code startInclusive > endExclusive} or if * {@code startInclusive} is negative - * @return the random long + * @return the random integer */ - public static long nextLong(final long startInclusive, final long endExclusive) { + public static int nextInt(final int startInclusive, final int endExclusive) { Validate.isTrue(endExclusive >= startInclusive, "Start value must be smaller or equal to end value."); Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative."); @@ -144,7 +172,7 @@ public class RandomUtils { return startInclusive; } - return startInclusive + nextLong(endExclusive - startInclusive); + return startInclusive + random().nextInt(endExclusive - startInclusive); } /** @@ -171,7 +199,7 @@ public class RandomUtils { long bits; long val; do { - bits = RANDOM.nextLong() >>> 1; + bits = random().nextLong() >>> 1; val = bits % n; } while (bits - val + (n - 1) < 0); @@ -180,7 +208,7 @@ public class RandomUtils { /** * <p> - * Returns a random double within the specified range. + * Returns a random long within the specified range. * </p> * * @param startInclusive @@ -190,9 +218,9 @@ public class RandomUtils { * @throws IllegalArgumentException * if {@code startInclusive > endExclusive} or if * {@code startInclusive} is negative - * @return the random double + * @return the random long */ - public static double nextDouble(final double startInclusive, final double endExclusive) { + public static long nextLong(final long startInclusive, final long endExclusive) { Validate.isTrue(endExclusive >= startInclusive, "Start value must be smaller or equal to end value."); Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative."); @@ -201,54 +229,25 @@ public class RandomUtils { return startInclusive; } - return startInclusive + ((endExclusive - startInclusive) * RANDOM.nextDouble()); + return startInclusive + nextLong(endExclusive - startInclusive); } - /** - * <p> Returns a random double within 0 - Double.MAX_VALUE </p> - * - * @return the random double - * @see #nextDouble(double, double) - * @since 3.5 - */ - public static double nextDouble() { - return nextDouble(0, Double.MAX_VALUE); + private static ThreadLocalRandom random() { + return ThreadLocalRandom.current(); } /** * <p> - * Returns a random float within the specified range. + * {@code RandomUtils} instances should NOT be constructed in standard + * programming. Instead, the class should be used as + * {@code RandomUtils.nextBytes(5);}. * </p> * - * @param startInclusive - * the smallest value that can be returned, must be non-negative - * @param endExclusive - * the upper bound (not included) - * @throws IllegalArgumentException - * if {@code startInclusive > endExclusive} or if - * {@code startInclusive} is negative - * @return the random float - */ - public static float nextFloat(final float startInclusive, final float endExclusive) { - Validate.isTrue(endExclusive >= startInclusive, - "Start value must be smaller or equal to end value."); - Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative."); - - if (startInclusive == endExclusive) { - return startInclusive; - } - - return startInclusive + ((endExclusive - startInclusive) * RANDOM.nextFloat()); - } - - /** - * <p> Returns a random float within 0 - Float.MAX_VALUE </p> - * - * @return the random float - * @see #nextFloat(float, float) - * @since 3.5 + * <p> + * This constructor is public to permit tools that require a JavaBean + * instance to operate. + * </p> */ - public static float nextFloat() { - return nextFloat(0, Float.MAX_VALUE); + public RandomUtils() { } }