All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.utils.common.RandomUtils Maven / Gradle / Ivy

package dev.utils.common;

import java.util.Random;

import dev.utils.JCLogUtils;

/**
 * detail: 随机工具类
 * @author Ttt
 */
public final class RandomUtils {

    private RandomUtils() {
    }

    // 日志 TAG
    private static final String TAG = RandomUtils.class.getSimpleName();

    // 0123456789
    private static final char[] NUMBERS = {
            48, 49, 50, 51, 52, 53, 54, 55, 56, 57
    };

    // abcdefghijklmnopqrstuvwxyz
    private static final char[] LOWER_CASE_LETTERS = {
            97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
            110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122
    };

    // ABCDEFGHIJKLMNOPQRSTUVWXYZ
    private static final char[] CAPITAL_LETTERS = {
            65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
            81, 82, 83, 84, 85, 86, 87, 88, 89, 90
    };

    // abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
    private static final char[] LETTERS = {
            97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
            111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66,
            67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
            84, 85, 86, 87, 88, 89, 90
    };

    // 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
    private static final char[] NUMBERS_AND_LETTERS = {
            48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102,
            103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
            116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72,
            73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90
    };

    /**
     * 获取伪随机 boolean 值
     * @param random Random
     * @return 随机 boolean 值
     */
    public static boolean nextBoolean(final Random random) {
        return random != null ? random.nextBoolean() : new Random().nextBoolean();
    }

    /**
     * 获取伪随机 byte[]
     * @param random Random
     * @param data   随机数据源
     * @return 随机 byte[]
     */
    public static byte[] nextBytes(
            final Random random,
            final byte[] data
    ) {
        if (random == null || data == null) return data;
        try {
            random.nextBytes(data);
        } catch (Exception ignored) {
        }
        return data;
    }

    /**
     * 获取伪随机 double 值
     * @param random Random
     * @return 随机 double 值
     */
    public static double nextDouble(final Random random) {
        return random != null ? random.nextDouble() : new Random().nextDouble();
    }

    /**
     * 获取伪随机高斯分布值
     * @param random Random
     * @return 伪随机高斯分布值
     */
    public static double nextGaussian(final Random random) {
        return random != null ? random.nextGaussian() : new Random().nextGaussian();
    }

    /**
     * 获取伪随机 float 值
     * @param random Random
     * @return 随机 float 值
     */
    public static float nextFloat(final Random random) {
        return random != null ? random.nextFloat() : new Random().nextFloat();
    }

    /**
     * 获取伪随机 int 值
     * @param random Random
     * @return 随机 int 值
     */
    public static int nextInt(final Random random) {
        return random != null ? random.nextInt() : new Random().nextInt();
    }

    /**
     * 获取伪随机 int 值 ( 该值介于 [0, n) 的区间 )
     * @param random Random
     * @param number 最大随机值
     * @return 随机介于 [0, n) 的区间值
     */
    public static int nextInt(
            final Random random,
            final int number
    ) {
        if (number <= 0) return 0;
        return random != null ? random.nextInt(number) : new Random().nextInt(number);
    }

    /**
     * 获取伪随机 long 值
     * @param random Random
     * @return 随机 long 值
     */
    public static long nextLong(final Random random) {
        return random != null ? random.nextLong() : new Random().nextLong();
    }

    // =

    /**
     * 获取伪随机 boolean 值
     * @return 随机 boolean 值
     */
    public static boolean nextBoolean() {
        return new Random().nextBoolean();
    }

    /**
     * 获取伪随机 byte[]
     * @param data 随机数据源
     * @return 随机 byte[]
     */
    public static byte[] nextBytes(final byte[] data) {
        if (data == null) return null;
        try {
            new Random().nextBytes(data);
        } catch (Exception ignored) {
        }
        return data;
    }

    /**
     * 获取伪随机 double 值
     * @return 随机 double 值
     */
    public static double nextDouble() {
        return new Random().nextDouble();
    }

    /**
     * 获取伪随机高斯分布值
     * @return 伪随机高斯分布值
     */
    public static double nextGaussian() {
        return new Random().nextGaussian();
    }

    /**
     * 获取伪随机 float 值
     * @return 随机 float 值
     */
    public static float nextFloat() {
        return new Random().nextFloat();
    }

    /**
     * 获取伪随机 int 值
     * @return 随机 int 值
     */
    public static int nextInt() {
        return new Random().nextInt();
    }

    /**
     * 获取伪随机 int 值 ( 该值介于 [0, n) 的区间 )
     * @param number 最大随机值
     * @return 随机介于 [0, n) 的区间值
     */
    public static int nextInt(final int number) {
        if (number <= 0) return 0;
        return new Random().nextInt(number);
    }

    /**
     * 获取伪随机 long 值
     * @return 随机 long 值
     */
    public static long nextLong() {
        return new Random().nextLong();
    }

    // =

    /**
     * 获取数字自定义长度的随机数
     * @param length 长度
     * @return 随机字符串
     */
    public static String getRandomNumbers(final int length) {
        return getRandom(NUMBERS, length);
    }

    /**
     * 获取小写字母自定义长度的随机数
     * @param length 长度
     * @return 随机字符串
     */
    public static String getRandomLowerCaseLetters(final int length) {
        return getRandom(LOWER_CASE_LETTERS, length);
    }

    /**
     * 获取大写字母自定义长度的随机数
     * @param length 长度
     * @return 随机字符串
     */
    public static String getRandomCapitalLetters(final int length) {
        return getRandom(CAPITAL_LETTERS, length);
    }

    /**
     * 获取大小写字母自定义长度的随机数
     * @param length 长度
     * @return 随机字符串
     */
    public static String getRandomLetters(final int length) {
        return getRandom(LETTERS, length);
    }

    /**
     * 获取数字、大小写字母自定义长度的随机数
     * @param length 长度
     * @return 随机字符串
     */
    public static String getRandomNumbersAndLetters(final int length) {
        return getRandom(NUMBERS_AND_LETTERS, length);
    }

    /**
     * 获取自定义数据自定义长度的随机数
     * @param source 随机的数据源
     * @param length 长度
     * @return 随机字符串
     */
    public static String getRandom(
            final String source,
            final int length
    ) {
        if (source == null) return null;
        return getRandom(source.toCharArray(), length);
    }

    /**
     * 获取 char[] 内的随机数
     * @param chars  随机的数据源
     * @param length 需要最终长度
     * @return 随机字符串
     */
    public static String getRandom(
            final char[] chars,
            final int length
    ) {
        if (length > 0 && chars != null && chars.length != 0) {
            StringBuilder builder = new StringBuilder(length);
            Random        random  = new Random();
            for (int i = 0; i < length; i++) {
                builder.append(chars[random.nextInt(chars.length)]);
            }
            return builder.toString();
        }
        return null;
    }

    /**
     * 获取 String[] 内的随机数
     * @param strings 随机的数据源
     * @param length  需要最终长度
     * @return 随机字符串
     */
    public static String getRandom(
            final String[] strings,
            final int length
    ) {
        if (length > 0 && strings != null && strings.length != 0) {
            StringBuilder builder = new StringBuilder(length);
            Random        random  = new Random();
            for (int i = 0; i < length; i++) {
                builder.append(strings[random.nextInt(strings.length)]);
            }
            return builder.toString();
        }
        return null;
    }

    /**
     * 获取 0 - 最大随机数之间的随机数
     * @param max 最大随机数
     * @return 随机介于 [0, max) 的区间值
     */
    public static int getRandom(final int max) {
        return getRandom(0, max);
    }

    /**
     * 获取两个数之间的随机数 ( 不含最大随机数, 需要 + 1)
     * @param min 最小随机数
     * @param max 最大随机数
     * @return 随机介于 [min, max) 的区间值
     */
    public static int getRandom(
            final int min,
            final int max
    ) {
        if (min > max) {
            return 0;
        } else if (min == max) {
            return min;
        }
        return min + new Random().nextInt(max - min);
    }

    // =

    // 内置洗牌算法
    // java.util.Collections.shuffle(List list);

    /**
     * 洗牌算法 ( 第一种 ) 随机置换指定的数组使用的默认源的随机性 ( 随机数据源小于三个, 则无效 )
     * @param objects 随机数据源
     * @return {@code true} success, {@code false} fail
     */
    public static boolean shuffle(final Object[] objects) {
        if (objects == null) return false;
        return shuffle(objects, getRandom(1, objects.length));
    }

    /**
     * 洗牌算法 ( 第一种 ) 随机置换指定的数组使用的默认源的随机性 ( 随机数据源小于三个, 则无效 )
     * @param objects      随机数据源
     * @param shuffleCount 洗牌次数
     * @return {@code true} success, {@code false} fail
     */
    public static boolean shuffle(
            final Object[] objects,
            final int shuffleCount
    ) {
        int length;
        if (shuffleCount > 0 && objects != null && (length = objects.length) >= shuffleCount) {
            for (int i = 1; i <= shuffleCount; i++) {
                int    random = getRandom(0, length - i);
                Object temp   = objects[length - i];
                objects[length - i] = objects[random];
                objects[random]     = temp;
            }
            return true;
        }
        return false;
    }

    /**
     * 洗牌算法 ( 第一种 ) 随机置换指定的数组使用的默认源的随机性 ( 随机数据源小于三个, 则无效 )
     * @param ints 随机数据源
     * @return 随机 int[]
     */
    public static int[] shuffle(final int[] ints) {
        if (ints == null) return null;
        return shuffle(ints, getRandom(1, ints.length));
    }

    /**
     * 洗牌算法 ( 第一种 ) 随机置换指定的数组使用的默认源的随机性 ( 随机数据源小于三个, 则无效 )
     * @param ints         随机数据源
     * @param shuffleCount 洗牌次数
     * @return 随机 int[]
     */
    public static int[] shuffle(
            final int[] ints,
            final int shuffleCount
    ) {
        int length;
        if (shuffleCount > 0 && ints != null && (length = ints.length) >= shuffleCount) {
            int[] out = new int[shuffleCount];
            for (int i = 1; i <= shuffleCount; i++) {
                int random = getRandom(0, length - i);
                out[i - 1] = ints[random];
                int temp = ints[length - i];
                ints[length - i] = ints[random];
                ints[random]     = temp;
            }
            return out;
        }
        return null;
    }

    // =

    /**
     * 洗牌算法 ( 第二种 ) 随机置换指定的数组使用的默认源的随机性
     * @param objects 随机数据源
     * @return {@code true} success, {@code false} fail
     */
    public static boolean shuffle2(final Object[] objects) {
        if (objects == null) return false;
        int len = objects.length;
        if (len > 0) {
            for (int i = 0; i < len - 1; i++) {
                int    idx  = (int) (Math.random() * (len - i));
                Object temp = objects[idx];
                objects[idx]         = objects[len - i - 1];
                objects[len - i - 1] = temp;
            }
            return true;
        }
        return false;
    }

    // =

    /**
     * 获取指定范围 int 值
     * @param origin 开始值
     * @param bound  范围值
     * @return 属于指定范围随机 int 值
     * @throws IllegalArgumentException 参数错误
     */
    public static int nextIntRange(
            final int origin,
            final int bound
    )
            throws IllegalArgumentException {
        if (origin > bound) {
            throw new IllegalArgumentException("bound must be greater than origin");
        } else if (origin == bound) {
            return origin;
        }
        Random random = new Random();
        int    n      = bound - origin;
        if (n > 0) {
            return random.nextInt(n) + origin;
        } else {
            int r;
            do {
                r = random.nextInt();
            } while (r < origin || r >= bound);
            return r;
        }
    }

    /**
     * 获取指定范围 long 值
     * @param origin 开始值
     * @param bound  范围值
     * @return 属于指定范围随机 long 值
     * @throws IllegalArgumentException 参数错误
     */
    public static long nextLongRange(
            final long origin,
            final long bound
    )
            throws IllegalArgumentException {
        if (origin > bound) {
            throw new IllegalArgumentException("bound must be greater than origin");
        } else if (origin == bound) {
            return origin;
        }
        Random random = new Random();
        long   r      = random.nextLong();
        long   n      = bound - origin, m = n - 1;
        if ((n & m) == 0L) // power of two
        {
            r = (r & m) + origin;
        } else if (n > 0L) {  // reject over-represented candidates
            for (long u = r >>> 1;            // ensure nonnegative
                 u + m - (r = u % n) < 0L;    // rejection check
                 u = random.nextLong() >>> 1) // retry
            {
            }
            r += origin;
        } else {              // range not representable as long
            while (r < origin || r >= bound) {
                r = random.nextLong();
            }
        }
        return r;
    }

    /**
     * 获取指定范围 double 值
     * @param origin 开始值
     * @param bound  范围值
     * @return 属于指定范围随机 double 值
     * @throws IllegalArgumentException 参数错误
     */
    public static double nextDoubleRange(
            final double origin,
            final double bound
    )
            throws IllegalArgumentException {
        if (origin > bound) {
            throw new IllegalArgumentException("bound must be greater than origin");
        } else if (origin == bound) {
            return origin;
        }
        double r = new Random().nextDouble();
        r = r * (bound - origin) + origin;
        if (r >= bound) // correct for rounding
        {
            r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
        }
        return r;
    }

    /**
     * 获取随机 int[]
     * @param streamSize         数组长度
     * @param randomNumberOrigin 开始值
     * @param randomNumberBound  结束值 ( 最大值范围 )
     * @return 指定范围随机 int[]
     */
    public static int[] ints(
            final int streamSize,
            final int randomNumberOrigin,
            final int randomNumberBound
    ) {
        if (randomNumberOrigin >= randomNumberBound) {
            return null;
        } else if (streamSize < 0) {
            return null;
        }
//        IntStream intStream = new Random().ints(streamSize, randomNumberOrigin, randomNumberBound);
//        return intStream.toArray();
        try {
            int[] ints = new int[streamSize];
            for (int i = 0; i < streamSize; i++) {
                ints[i] = nextIntRange(randomNumberOrigin, randomNumberBound);
            }
            return ints;
        } catch (Exception e) {
            JCLogUtils.eTag(TAG, e, "ints");
        }
        return null;
    }

    /**
     * 获取随机 long[]
     * @param streamSize         数组长度
     * @param randomNumberOrigin 开始值
     * @param randomNumberBound  结束值 ( 最大值范围 )
     * @return 指定范围随机 long[]
     */
    public static long[] longs(
            final int streamSize,
            final long randomNumberOrigin,
            final long randomNumberBound
    ) {
        if (randomNumberOrigin >= randomNumberBound) {
            return null;
        } else if (streamSize < 0) {
            return null;
        }
//        LongStream longStream = new Random().longs(streamSize, randomNumberOrigin, randomNumberBound);
//        return longStream.toArray();
        try {
            long[] longs = new long[streamSize];
            for (int i = 0; i < streamSize; i++) {
                longs[i] = nextLongRange(randomNumberOrigin, randomNumberBound);
            }
            return longs;
        } catch (Exception e) {
            JCLogUtils.eTag(TAG, e, "longs");
        }
        return null;
    }

    /**
     * 获取随机 double[]
     * @param streamSize         数组长度
     * @param randomNumberOrigin 开始值
     * @param randomNumberBound  结束值 ( 最大值范围 )
     * @return 指定范围随机 double[]
     */
    public static double[] doubles(
            final int streamSize,
            final double randomNumberOrigin,
            final double randomNumberBound
    ) {
        if (randomNumberOrigin >= randomNumberBound) {
            return null;
        } else if (streamSize < 0) {
            return null;
        }
//        DoubleStream doubleStream = new Random().doubles(streamSize, randomNumberOrigin, randomNumberBound);
//        return doubleStream.toArray();
        try {
            double[] doubles = new double[streamSize];
            for (int i = 0; i < streamSize; i++) {
                doubles[i] = nextDoubleRange(randomNumberOrigin, randomNumberBound);
            }
            return doubles;
        } catch (Exception e) {
            JCLogUtils.eTag(TAG, e, "doubles");
        }
        return null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy