业务中不少地方用到根据权重来抽奖的逻辑,封装出公用的逻辑。 @Service public class GeneratePrizeByWeightService { private static final Logger LOG = LoggerFactory.getLogger(GeneratePrizeByWeightService.class); public String getReward(String rewardStr) { if(StringUtils.isEmpty(rewardStr)) { return ""; } List<ActiveTaskConfValueDto> rewardList = JSON.parseArray(rewardStr, ActiveTaskConfValueDto.class); if(rewardList == null || rewardList.size() == 0) { return ""; } return getRewardByWeight(rewardList); } public String getRewardByWeight(List<ActiveTaskConfValueDto> prizes) { int random = -1; try { //计算总权重 double sumWeight = 0; for (ActiveTaskConfValueDto prize : prizes) { sumWeight += prize.getWeight(); } //产生随机数 double randomNumber; randomNumber = Math.random(); //根据随机数在所有奖品分布的区域并确定所抽奖品 double beginRange = 0; double endRange = 0; for (int i = 0; i < prizes.size(); i++) { endRange += Double.parseDouble(String.valueOf(prizes.get(i).getWeight())) / sumWeight; if (i == 0) { beginRange = 0; } else { beginRange += Double.parseDouble(String.valueOf(prizes.get(i - 1).getWeight())) / sumWeight; } if (randomNumber >= beginRange && randomNumber <= endRange) { random = i; break; } } } catch (Exception e) { LOG.info("[GeneratePrizeByWeightService.getRewardByWeight] 根据权重获取奖励异常,e:{}", e); return ""; } return prizes.get(random).getRpCode(); } }
public class ActiveTaskConfValueDto { private String rpCode; private int weight; public String getRpCode() { return rpCode; } public void setRpCode(String rpCode) { this.rpCode = rpCode; } public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } }