public class LotteryUtils { public static int lottery(List<BigDecimal> originRates) { BigDecimal min = Collections.min(originRates); BigDecimal sumRate; if (min.compareTo(new BigDecimal(1)) >= 0) { sumRate = new BigDecimal(100); } else { String t = String.valueOf(min); String[] data = t.split("\\."); int length = data[1].length(); int sum = 1; for (int i = 1; i <= length; i++) { sum = sum * 10; } sumRate = new BigDecimal(sum * 100); } // 计算每个物品在总概率的基础下的概率情况 List<Integer> sortOriginRates = new ArrayList<>(); //sortOriginRates.add(1); BigDecimal tempSumRate = new BigDecimal(0); for (BigDecimal rate : originRates) { tempSumRate = tempSumRate.add(rate); sortOriginRates.add(tempSumRate.divide(new BigDecimal(100)).multiply(sumRate).intValue()); } // 根据区块值来获取抽取到的物品索引 Integer nextDouble = (int) (Math.random() * sumRate.intValue() + 1); sortOriginRates.add(nextDouble); Collections.sort(sortOriginRates); return sortOriginRates.indexOf(nextDouble); } }
时间: 2024-02-14 10:22:43 浏览: 65
一个java程序员的经验总结
这是一个抽奖工具类,其中的 `lottery` 方法用于在一组给定的概率下进行抽奖。这个方法的输入参数是一个 `List` 类型的 `originRates`,其中包含了每个物品被抽中的概率。具体地说,这些概率被表示为 `BigDecimal` 类型的数值,且按照 `originRates` 中的顺序排列。例如,如果 `originRates` 的第一个元素表示物品 A 被抽中的概率,第二个元素表示物品 B 被抽中的概率,那么在进行抽奖时,物品 A 会被抽中的概率为 `originRates.get(0)`,物品 B 会被抽中的概率为 `originRates.get(1)`。
在方法中,首先通过 `Collections.min` 方法找到 `originRates` 中的最小值,并将其保存在 `min` 变量中。如果最小值大于等于 1,说明所有的物品概率都是百分比形式,因此将 `sumRate` 的值设置为 100。否则,说明至少有一项概率是小数形式,需要将所有的概率乘以一个倍数,使它们变成整数,以方便后面的计算。具体来说,这个倍数就是一个比该小数位数多一位的 10 的整数次幂,例如,如果最小概率是 0.001,那么倍数就是 10000,因为需要将所有的概率乘以 10000 才能将小数点向右移动 4 位,变成整数。
接下来,根据每个物品在总概率下的概率情况,计算出一个新的概率列表 `sortOriginRates`。这个列表中的每个元素表示在抽奖时,前面的物品都没有被抽中的情况下,当前物品被抽中的概率。例如,如果 `sortOriginRates` 的第一个元素是 30,那么说明在前面的物品都没有被抽中的情况下,当前物品被抽中的概率是 30/10000。最后,根据随机生成的一个区块值 `nextDouble`,从 `sortOriginRates` 中找到对应的物品索引,并返回该索引作为抽奖的结果。
值得注意的是,这个方法中没有考虑多线程的情况,如果需要在多线程环境下使用,可能需要添加一些同步措施来保证线程安全。
阅读全文