java实现抽奖功能
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { Main m = new Main(); m.draw( int mode); } /** * 初始化奖池 * * @return 奖池 */ public List<AwardItem> initAwardItem() { List<AwardItem> list = new ArrayList<>(); //此处查数据库 获取 库存>0 且 概率>0 的奖项 list.add(new AwardItem(1, 1, 10000, "iphone")); list.add(new AwardItem(2, 3, 10000, "耳机")); list.add(new AwardItem(3, 5, 10000, "周卡")); list.add(new AwardItem(4, 10, 10000, "次卡")); list.add(new AwardItem(5, 20, 10000, "100元券")); list.add(new AwardItem(6, 30, 10000, "300元券")); list.add(new AwardItem(7, 50, 10000, "500元券")); // 若无结果,则提示活动结束 if (list.size() == 0) { throw new RuntimeException("正在努力补货中......"); } // 业务处理,过滤掉本次不能抽中的奖项(自行处理) return list; } /** * 抽奖 * * @param mode 1单次抽 2连连抽 */ void draw(int mode) { String uid = null; // 当前登录用户 // 1 检查 是否当前用户还有抽奖次数 int drawCount = 0; // 此处查询数据库当前用户本次活动还剩余的抽奖次数 if (drawCount < 1) { throw new RuntimeException("您的抽奖次数已经用完"); } // 计算本次循环抽多少次 // 1、如果是单次抽 循环1次 int count = 1; // 2、如果是连连抽 if (mode == 2) { count = 10; // 查询连连抽的次数 } int usedCount = 0; //本轮抽奖所使用的次数 while (usedCount < count) { usedCount++; List<AwardItem> list = initAwardItem(); int awardItemId = doDraw(list); if (awardItemId == -1) { throw new RuntimeException("未中奖"); } // 用当前奖品ID加redis锁(key='DRAW_ITEM_'+awardItemId),扣库存,剪掉用户本次抽奖次数 try { // 处理中奖的数据 processingTheWinningData(awardItemId, uid); } finally { // 此处解锁redis锁(key='DRAW_ITEM_'+awardItemId) } } } /** * 处理中奖数据 * * @param awardItemID 奖项id * @param uid 用户id */ void processingTheWinningData(int awardItemID, String uid) { // 插入中奖记录 扣减中奖奖品的库存 和 用户抽奖次数 // 此处加事务 } /** * 执行抽奖 * * @param list 奖池 * @return 中奖的奖项ID */ int doDraw(List<AwardItem> list) { // 计算所有奖项权重总和 int sumWeight = list.stream().mapToInt(AwardItem::getProbability).sum(); // 此次中奖的随机数 int randomNum = (int) (Math.random() * sumWeight); int min = 0; int max = 0; int selected = -1; // 遍历奖池,找出中奖的奖项 for (int i = 0; i < list.size(); i++) { if (i > 0) { min = max; } max += list.get(i).getProbability(); if (randomNum >= min && randomNum < max) { selected = i; break; } } return selected == -1 ? selected : list.get(selected).getId(); } /** * 奖项 */ class AwardItem { int id; int probability; // 概率 int stock; // 库存 String name; public AwardItem(int id, int probability, int stock, String name) { this.id = id; this.probability = probability; this.stock = stock; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getProbability() { return probability; } public void setProbability(int probability) { this.probability = probability; } public int getStock() { return stock; } public void setStock(int stock) { this.stock = stock; } public String getName() { return name; } public void setName(String name) { this.name = name; } } }