Java如何根据随机生成的概率值匹配最接近的对应枚举类型
实现方案
基础实现(适合枚举项数量较少场景)
遍历所有枚举实例,计算每个枚举的chance值与目标随机值的绝对差值,返回差值最小的枚举实例即可,代码复杂度低,足够覆盖绝大多数枚举使用场景。
@RequiredArgsConstructor enum Types{ TYPE_1(0.20f), TYPE_2(0.05f), TYPE_3(0.30f), TYPE_4(0.12f), TYPE_5(0.03f); @Getter private final float chance; // 匹配最接近概率的枚举方法 public static Types getByClosestChance(float target) { Types closest = null; float minDiff = Float.MAX_VALUE; for (Types type : Types.values()) { float diff = Math.abs(type.chance - target); if (diff < minDiff) { minDiff = diff; closest = type; } } return closest; } }
使用示例:
import java.util.Random; public class Test { public static void main(String[] args) { Random random = new Random(); // 生成0~1之间的随机浮点数 float randomValue = random.nextFloat(); Types matchedType = Types.getByClosestChance(randomValue); System.out.printf("随机值:%.2f,匹配到的枚举:%s,对应概率:%.2f%n", randomValue, matchedType.name(), matchedType.getChance()); } }
优化实现(适合枚举项数量较多场景)
提前将枚举按chance值升序排序,使用二分查找定位目标值的插入位置,仅需比较插入位置前后两个枚举的差值即可得到最接近项,时间复杂度从O(n)降至O(logn)。
@RequiredArgsConstructor enum Types{ TYPE_1(0.20f), TYPE_2(0.05f), TYPE_3(0.30f), TYPE_4(0.12f), TYPE_5(0.03f); @Getter private final float chance; // 预排序的枚举数组 private static final Types[] SORTED_TYPES; static { // 类初始化时完成排序,仅执行一次 SORTED_TYPES = Arrays.stream(Types.values()) .sorted(Comparator.comparingDouble(Types::getChance)) .toArray(Types[]::new); } public static Types getByClosestChance(float target) { // 二分查找定位插入位置 int index = Arrays.binarySearch(SORTED_TYPES, target, Comparator.comparingDouble(Types::getChance)); if (index >= 0) { // 完全匹配直接返回 return SORTED_TYPES[index]; } int insertPos = - (index + 1); // 边界情况处理 if (insertPos == 0) { return SORTED_TYPES[0]; } if (insertPos == SORTED_TYPES.length) { return SORTED_TYPES[SORTED_TYPES.length - 1]; } // 比较插入点前后两个元素的差值,返回更接近的 float diffPrev = Math.abs(SORTED_TYPES[insertPos - 1].chance - target); float diffNext = Math.abs(SORTED_TYPES[insertPos].chance - target); return diffPrev <= diffNext ? SORTED_TYPES[insertPos - 1] : SORTED_TYPES[insertPos]; } }
注意事项
如果对浮点数精度要求极高,可将float转为BigDecimal计算差值,避免精度误差导致匹配错误;如果出现多个枚举和目标值差值相同的情况,可根据业务需求调整差值相等时的优先级判断逻辑。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

