package com.ff.base.utils; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Optional; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; public class NumberUtils { /** * 计算比例 * * @param totalCount 总计数 * @param remainingCount 剩余计数 * @param scale 规模 * @return {@link BigDecimal } */ public static BigDecimal calculateProportion(Number totalCount, Number remainingCount, int scale) { BigDecimal total = Optional.ofNullable(totalCount) .map(val -> new BigDecimal(val.toString())) .orElse(BigDecimal.ZERO); BigDecimal remaining = Optional.ofNullable(remainingCount) .map(val -> new BigDecimal(val.toString())) .orElse(BigDecimal.ZERO); if (total.compareTo(BigDecimal.ZERO) != 0) { return remaining.divide(total, scale, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2, RoundingMode.DOWN); } else { return BigDecimal.ZERO; } } /** * 在两个 BigDecimal 数值之间生成一个随机数 * * @param min 最小值 * @param max 最大值 * @return 随机生成的 BigDecimal 数值 */ public static BigDecimal getRandomBigDecimal(BigDecimal min, BigDecimal max) { // 确保 min 小于 max if (min.compareTo(max) > 0) { throw new IllegalArgumentException("最小值应小于最大值"); } // 计算范围的差值 BigDecimal range = max.subtract(min); // 使用 ThreadLocalRandom 生成 [0, 1) 之间的随机数 double randomDouble = ThreadLocalRandom.current().nextDouble(); // 计算随机值 BigDecimal randomValue = min.add(range.multiply(BigDecimal.valueOf(randomDouble))); // 设置保留两位小数 return randomValue.setScale(2, RoundingMode.HALF_UP); } /** * 生成随机码 * * @return {@link String } */ public static String generateRandomCode() { Random random = new Random(); StringBuilder sb = new StringBuilder(); // 每位字符可以是字母(A-Z, a-z)或数字(0-9) for (int i = 0; i < 3; i++) { int choice = random.nextInt(3); if (choice == 0) { // 随机字母(大写或小写) char letter = (char) ('A' + random.nextInt(26)); sb.append(letter); } else if (choice == 1) { // 随机小写字母 char letter = (char) ('a' + random.nextInt(26)); sb.append(letter); } else { // 随机数字 sb.append(random.nextInt(10)); } } return sb.toString(); } }