核心是用随机数模拟“抽中”动作,关键在于满足业务规则:允许重复中奖则直接随机索引取值;需去重则边抽边删;加权抽奖用累积权重法映射概率区间;调试时可用Random固定种子保证可重现性。

核心是用随机数模拟“抽中”动作,关键不在生成随机数本身,而是如何让结果符合业务规则——比如是否允许重复中奖、是否需要权重、是否要排除已中奖者等。
基础逻辑:从集合中随机抽取一个元素
最常见场景是“从名单里抽一个幸运儿”。用 Random 或 ThreadLocalRandom(推荐,线程安全且性能更好)获取索引:
- 把所有参与人存入
List<String>或其他容器 - 生成
0到list.size() - 1的随机整数作为下标 - 取出对应元素即为中奖者
示例代码片段:
List<String> users = Arrays.asList("张三", "李四", "王五");int index = ThreadLocalRandom.current().nextInt(users.size());
String winner = users.get(index);
去重抽奖:抽完即移除,避免重复中奖
如果一次抽多个、且每人只能中一次,不能简单重复随机取索引(可能重复),应边抽边删:
立即学习“Java免费学习笔记(深入)”;
- 用
ArrayList存储可选人员 - 每次生成随机索引后,用
remove(int index)取出并移除该人 - 后续随机范围自动缩小,天然去重
注意:不要在遍历中直接 remove 原列表(易跳过元素),而是用 while 循环 + size 控制次数。
加权抽奖:按概率分配中奖机会
比如 VIP 用户中奖概率是普通用户的 3 倍,可用“累积权重法”:
- 为每个人分配权重(如 VIP=3,普通=1)
- 计算总权重和,生成
[0, total)内的随机数 - 遍历用户,累加权重,当累计值首次 ≥ 随机数时,此人中奖
本质是把概率映射成一段连续区间,随机数落在哪段就选谁。比多次随机+判断更高效、更准确。
公平性与可重现性:必要时固定随机种子
调试或审计时,可能需要每次运行结果一致:
- 创建
Random实例时传入固定 long 值(如new Random(12345L)) -
ThreadLocalRandom不支持设种子,此时应改用Random - 生产环境通常不设种子,确保真正随机
不复杂但容易忽略。


















