Java 中向 List 插入随机整数时如何避免出现重复值
现有代码存在的问题
- 索引越界异常:
i每次循环都会被重置为0,判断条件中调用options.get(i-1)等价于options.get(-1),第一次进入循环执行判断时就会抛出索引越界错误,代码无法正常运行。 - 去重逻辑完全失效:即使修复了索引问题,原有逻辑仅校验了生成的随机数和列表前一个元素是否相等,没有校验与列表中所有已存元素是否重复,依然会插入重复值。
- 死循环风险:如果
[answer-8, answer+8)区间内排除answer本身后的可用整数数量小于4,循环永远无法满足终止条件,会一直无限执行。 - 查询效率低下:即使补全全量重复校验,基于List的
contains方法做重复判断的复杂度是O(n),插入n个元素的整体复杂度为O(n²),数据量稍大时效率很低。
修复方案
方案1:仅基于List实现(适合小数据量场景)
// 先校验取值区间可用元素是否足够,避免死循环 int rangeStart = answer - 8; int rangeEnd = answer + 8; int availableCount = (rangeEnd - rangeStart) - 1; // 排除answer本身 if (availableCount < 4) { throw new IllegalArgumentException("取值区间可用元素不足,无法生成4个不重复值"); } while (options.size() < 4) { int random = ThreadLocalRandom.current().nextInt(rangeStart, rangeEnd); // 排除等于answer的情况,同时校验是否已存在列表中 if (random != answer && !options.contains(random)) { options.add(random); } }
方案2:使用Set中转(推荐,去重效率更高)
int rangeStart = answer - 8; int rangeEnd = answer + 8; int availableCount = (rangeEnd - rangeStart) - 1; if (availableCount < 4) { throw new IllegalArgumentException("取值区间可用元素不足,无法生成4个不重复值"); } Set<Integer> tempSet = new HashSet<>(); while (tempSet.size() < 4) { int random = ThreadLocalRandom.current().nextInt(rangeStart, rangeEnd); if (random != answer) { tempSet.add(random); // Set自动去重,无需手动判断重复 } } // 转成目标List集合 options.addAll(tempSet);
内容的提问来源于stack exchange,提问作者fajrulalam
相关产品推荐
相关产品推荐

