如何正确使用while循环将用户输入存入两个ArrayList并解决输入异常?
问题原因分析
你的代码出现这个问题,核心是Scanner的nextDouble()方法不会处理输入后的换行符,导致输入缓冲区里残留了换行,干扰了后续的nextLine()读取:
- 第一次循环:你输入姓名后按回车,
nextLine()会读取姓名内容并丢弃末尾的换行符;接着输入金额按回车,nextDouble()只读取数字部分,把回车(换行符)留在了输入缓冲区里。 - 第二次循环:
nextLine()一启动就读取到了缓冲区里残留的换行符,直接返回空字符串,所以程序瞬间跳过姓名输入,立刻提示输入金额;这时候你输入的内容(本应是姓名)会被nextDouble()尝试解析成Double,自然抛出InputMismatchException。
解决方案
这里给你两种靠谱的修复方式,按需选择:
方法1:清理nextDouble()后的换行符
在调用nextDouble()之后,额外调用一次userInput.nextLine()来吃掉残留的换行符,确保下一次nextLine()能正常读取用户输入:
Scanner userInput = new Scanner(System.in); ArrayList<String> customerName = new ArrayList<>(); ArrayList<Double> customerSpend = new ArrayList<>(); double checkUserInput = 1; while (checkUserInput != 0) { System.out.println("Please enter the customer name"); customerName.add(userInput.nextLine()); System.out.println("Please enter the customer amount"); double amount = userInput.nextDouble(); // 关键:清理nextDouble()留下的换行符 userInput.nextLine(); customerSpend.add(amount); if (amount == 0) { checkUserInput = 0; } } // 打印时添加分隔符,可读性更好 for (int i = 0; i < customerName.size(); i++) { System.out.println("Customer: " + customerName.get(i) + ", Amount: " + customerSpend.get(i)); }
方法2:统一用nextLine()读取所有输入(更推荐)
这种方式可以彻底避免Scanner的换行符陷阱,还能增加输入验证,防止用户输入非数字金额时直接崩溃:
Scanner userInput = new Scanner(System.in); ArrayList<String> customerName = new ArrayList<>(); ArrayList<Double> customerSpend = new ArrayList<>(); while (true) { System.out.println("Please enter the customer name"); String name = userInput.nextLine(); System.out.println("Please enter the customer amount (enter 0 to exit)"); String amountStr = userInput.nextLine(); // 验证金额输入是否合法 double amount; try { amount = Double.parseDouble(amountStr); } catch (NumberFormatException e) { System.out.println("Oops, that's not a valid number! Please try again."); continue; } customerName.add(name); customerSpend.add(amount); // 输入0时结束循环 if (amount == 0) { break; } } // 打印结果 for (int i = 0; i < customerName.size(); i++) { System.out.println("Customer: " + customerName.get(i) + ", Amount: " + customerSpend.get(i)); }
额外提示
- 如果希望用户可以通过输入
0直接结束程序(不需要输入金额),可以在读取姓名后判断if (name.equals("0")) break;,这样逻辑更灵活。 - 注意
double类型的精度问题,如果是处理金额,推荐使用BigDecimal来避免精度丢失。
内容的提问来源于stack exchange,提问作者Friso Hoogland
相关产品推荐
相关产品推荐

