diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/RandomTools.java b/src/main/java/xyz/zhouxy/plusone/commons/util/RandomTools.java index 69eb555..6afc578 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/RandomTools.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/RandomTools.java @@ -20,6 +20,8 @@ import java.security.SecureRandom; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; +import javax.annotation.Nonnull; + public final class RandomTools { public static final SecureRandom DEFAULT_SECURE_RANDOM = new SecureRandom(); @@ -30,7 +32,7 @@ public final class RandomTools { /** * 使用传入的随机数生成器,生成指定长度的字符串 - * + * * @param random 随机数生成器。根据需要可以传入 * {@link java.util.concurrent.ThreadLocalRandom}、{@link java.security.SecureRandom} * 等,不为空 @@ -38,7 +40,68 @@ public final class RandomTools { * @param length 字符串长度 * @return 随机字符串 */ - public static String randomStr(Random random, char[] sourceCharacters, int length) { + public static String randomStr(@Nonnull Random random, @Nonnull char[] sourceCharacters, int length) { + AssertTools.checkArgumentNotNull(random, "Random cannot be null."); + AssertTools.checkArgumentNotNull(sourceCharacters, "Source characters cannot be null."); + AssertTools.checkArgument(length >= 0, "The length should be greater than or equal to zero."); + return randomStrInternal(random, sourceCharacters, length); + } + + public static String randomStr(@Nonnull char[] sourceCharacters, int length) { + AssertTools.checkArgumentNotNull(sourceCharacters, "Source characters cannot be null."); + AssertTools.checkArgument(length >= 0, "The length should be greater than or equal to zero."); + return randomStrInternal(ThreadLocalRandom.current(), sourceCharacters, length); + } + + public static String secureRandomStr(@Nonnull char[] sourceCharacters, int length) { + AssertTools.checkArgumentNotNull(sourceCharacters, "Source characters cannot be null."); + AssertTools.checkArgument(length >= 0, "The length should be greater than or equal to zero."); + return randomStrInternal(DEFAULT_SECURE_RANDOM, sourceCharacters, length); + } + + /** + * 使用传入的随机数生成器,生成指定长度的字符串 + * + * @param random 随机数生成器。根据需要可以传入 + * {@link java.util.concurrent.ThreadLocalRandom}、{@link java.security.SecureRandom} + * 等,不为空 + * @param sourceCharacters 字符池。字符串的字符将在数组中选,不为空 + * @param length 字符串长度 + * @return 随机字符串 + */ + public static String randomStr(@Nonnull Random random, @Nonnull String sourceCharacters, int length) { + AssertTools.checkArgumentNotNull(random, "Random cannot be null."); + AssertTools.checkArgumentNotNull(sourceCharacters, "Source characters cannot be null."); + AssertTools.checkArgument(length >= 0, "The length should be greater than or equal to zero."); + return randomStrInternal(random, sourceCharacters, length); + } + + public static String randomStr(@Nonnull String sourceCharacters, int length) { + AssertTools.checkArgumentNotNull(sourceCharacters, "Source characters cannot be null."); + AssertTools.checkArgument(length >= 0, "The length should be greater than or equal to zero."); + return randomStrInternal(ThreadLocalRandom.current(), sourceCharacters, length); + } + + public static String secureRandomStr(@Nonnull String sourceCharacters, int length) { + AssertTools.checkArgumentNotNull(sourceCharacters, "Source characters cannot be null."); + AssertTools.checkArgument(length >= 0, "The length should be greater than or equal to zero."); + return randomStrInternal(DEFAULT_SECURE_RANDOM, sourceCharacters, length); + } + + /** + * 使用传入的随机数生成器,生成指定长度的字符串 + * + * @param random 随机数生成器。根据需要可以传入 + * {@link java.util.concurrent.ThreadLocalRandom}、{@link java.security.SecureRandom} + * 等,不为空 + * @param sourceCharacters 字符池。字符串的字符将在数组中选,不为空 + * @param length 字符串长度 + * @return 随机字符串 + */ + private static String randomStrInternal(@Nonnull Random random, @Nonnull char[] sourceCharacters, int length) { + if (length == 0) { + return StringTools.EMPTY_STRING; + } final char[] result = new char[length]; for (int i = 0; i < length; i++) { result[i] = sourceCharacters[random.nextInt(sourceCharacters.length)]; @@ -46,17 +109,9 @@ public final class RandomTools { return String.valueOf(result); } - public static String randomStr(char[] sourceCharacters, int length) { - return randomStr(ThreadLocalRandom.current(), sourceCharacters, length); - } - - public static String secureRandomStr(char[] sourceCharacters, int length) { - return randomStr(DEFAULT_SECURE_RANDOM, sourceCharacters, length); - } - /** * 使用传入的随机数生成器,生成指定长度的字符串 - * + * * @param random 随机数生成器。根据需要可以传入 * {@link java.util.concurrent.ThreadLocalRandom}、{@link java.security.SecureRandom} * 等,不为空 @@ -64,7 +119,10 @@ public final class RandomTools { * @param length 字符串长度 * @return 随机字符串 */ - public static String randomStr(Random random, String sourceCharacters, int length) { + private static String randomStrInternal(@Nonnull Random random, @Nonnull String sourceCharacters, int length) { + if (length == 0) { + return StringTools.EMPTY_STRING; + } final char[] result = new char[length]; for (int i = 0; i < length; i++) { result[i] = sourceCharacters.charAt(random.nextInt(sourceCharacters.length())); @@ -72,14 +130,6 @@ public final class RandomTools { return String.valueOf(result); } - public static String randomStr(String sourceCharacters, int length) { - return randomStr(ThreadLocalRandom.current(), sourceCharacters, length); - } - - public static String secureRandomStr(String sourceCharacters, int length) { - return randomStr(DEFAULT_SECURE_RANDOM, sourceCharacters, length); - } - private RandomTools() { throw new IllegalStateException("Utility class"); } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/StringTools.java b/src/main/java/xyz/zhouxy/plusone/commons/util/StringTools.java index 5d788d4..951ead0 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/StringTools.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/StringTools.java @@ -21,6 +21,8 @@ import com.google.common.annotations.Beta; @Beta public class StringTools { + public static final String EMPTY_STRING = ""; + public static boolean isNotBlank(final String cs) { if (cs == null || cs.isEmpty()) { return false;