Java二维数组每行生成不重复随机数遇无限循环问题
问题排查与解决方案:生成乐透号码时的无限循环问题
核心问题分析
1. 布尔数组重置错误(无限循环直接诱因)
在generateLottos方法中,行处理后的数组重置逻辑存在两处致命错误:
if (i!=0) { for (int k=1; k<= MAX_NUM; k++){ numbers[i] = false; // 错误:用循环变量i而非k作为数组索引 } }
- 代码意图是重置
numbers数组所有元素为false,但实际仅修改了numbers[i]这一个固定位置的值,其余元素的标记状态完全保留第一行的结果。 - 处理第二行及后续行时,
do-while循环会持续尝试生成已被标记的数字,最终陷入无限循环。 if(i!=0)判断逻辑错误:第一行处理完成后同样需要重置数组,否则第二行无法生成新的不重复号码。
2. Scanner提前关闭的潜在风险
getLottosArr方法中提前调用scanner.close()会关闭标准输入流,若后续代码需要读取输入会直接抛出NoSuchElementException,属于不良编码习惯。
修复后的完整代码
LottoSorting类修复版
import java.util.Scanner; class LottoSorting { private static final Scanner scanner = new Scanner(System.in); private static final int drawSize = 15; // 每行号码数量 private static final int MAX_NUM = 49; // 最大生成数字 // 获取用户指定行数的二维数组 public int[][] getLottosArr(){ System.out.println("请输入要生成的注数: "); int drawsNum = scanner.nextInt(); return new int[drawsNum][drawSize]; } public int[][] generateLottos(int[][] arrOfLottos){ int random; for (int i=0; i< arrOfLottos.length; i++){ // 每行重新初始化布尔数组,彻底避免重置错误 boolean[] numbers = new boolean[MAX_NUM + 1]; for (int j=0; j<arrOfLottos[i].length; j++){ do { // 简化随机数生成:强制转int等价于floor操作 random = (int)(Math.random() * MAX_NUM + 1); }while (numbers[random]); arrOfLottos[i][j] = random; numbers[random] = true; } } return arrOfLottos; } public void printArray(int[][] lottosArr){ System.out.println("生成的乐透号码:"); for (int i=0; i< lottosArr.length; i++){ System.out.printf("\n第%d注: ", i+1); for (int j=0; j<lottosArr[i].length; j++){ if (j != 0) { System.out.print(" "); } System.out.printf("%02d", lottosArr[i][j]); // 格式化输出,保持对齐 } } scanner.close(); // 所有输入操作完成后再关闭流 } }
Lotto主类
class Lotto { public static void main(String[] args) { LottoSorting lottoSorting = new LottoSorting(); lottoSorting.printArray(lottoSorting.generateLottos(lottoSorting.getLottosArr())); } }
关键优化点说明
- 数组重置逻辑重构:将
boolean[] numbers声明移至外层循环内部,每行处理时重新创建数组,彻底规避重置错误,代码更简洁可靠。 - 随机数生成简化:
(int)(Math.random() * MAX_NUM + 1)与原floor写法效果一致,但代码更精简。 - Scanner关闭时机调整:将关闭操作移至
printArray方法末尾,确保所有输入流程完成后再关闭标准输入流。 - 输出格式优化:使用
printf格式化号码输出,结果更整齐易读。
内容的提问来源于stack exchange,提问作者Sszymon877
相关产品推荐
相关产品推荐

