Java从含重复元素列表抽取不重复获奖者的代码问题排查
抽奖程序重复获奖问题排查与修复
问题核心原因
你的代码逻辑存在两个关键错误,导致同一玩家重复获奖:
- 只检查券索引是否重复,未验证玩家身份:你用
WinnerNumberList.contains(randomNumber)判断的是「是否抽过同一张券」,但同一玩家的不同券索引是不同的,所以这个判断无法阻止同一玩家的多张券被选中。 - 内层循环逻辑混乱:内层循环遍历已中奖索引时,只要遇到一个与当前玩家不同的已中奖玩家,就会直接添加当前索引,而不是检查所有已中奖玩家都与当前玩家不同才添加。比如已中奖列表里有PlayerA和PlayerB,现在抽到PlayerB的另一张券,内层循环先对比PlayerA,发现不同就直接添加,完全没检查到已存在PlayerB的获奖记录。
修复方案
换个思路:用一个Set来记录已经中奖的玩家名称(因为Set天然去重),每次抽取时先验证玩家是否已中奖,再决定是否加入获奖列表。
修正后的代码示例:
import java.util.ArrayList; import java.util.HashSet; import java.util.Random; import java.util.Set; // 初始化示例数据 ArrayList<String> myEntryList = new ArrayList<>(); myEntryList.add("PlayerA"); myEntryList.add("PlayerB"); myEntryList.add("PlayerB"); myEntryList.add("PlayerC"); myEntryList.add("PlayerD"); myEntryList.add("PlayerE"); myEntryList.add("PlayerF"); int amountOfWinners = 3; // 设定获奖人数 Random rng = new Random(); ArrayList<Integer> WinnerNumberList = new ArrayList<>(); Set<String> winningPlayers = new HashSet<>(); // 记录已中奖玩家 while (WinnerNumberList.size() < amountOfWinners) { Integer randomNumber = rng.nextInt(myEntryList.size()); String currentPlayer = myEntryList.get(randomNumber); // 检查该玩家是否未中奖 if (!winningPlayers.contains(currentPlayer)) { WinnerNumberList.add(randomNumber); winningPlayers.add(currentPlayer); } } // 验证输出 System.out.println("获奖券索引:" + WinnerNumberList); System.out.println("获奖玩家:"); for (int idx : WinnerNumberList) { System.out.println(myEntryList.get(idx)); }
方案优势
Set<String> winningPlayers自动去重,确保同一个玩家只会被记录一次。- 每次抽取先判断玩家是否已在获奖集合中,从根源上避免同一玩家重复获奖。
- 逻辑简洁清晰,比原代码的嵌套循环更容易维护和理解。
内容的提问来源于stack exchange,提问作者faelwen
相关产品推荐
相关产品推荐

