Scanner读取用户输入存入ArrayList时循环无法正常终止的问题
问题原因
Scanner.hasNext()的默认行为是忽略所有空白字符(空格、换行、制表符等),只会等待下一个非空白的输入项。所以你输入空白(直接回车)时,它不会返回false,而是继续等待有效输入,只有当输入流被强制终止(比如Unix按Ctrl+D,Windows按Ctrl+Z)时才会结束循环。
解决方案
根据你需要支持任意数量输入(包括0个)的需求,这里给你几种可行的实现方式:
1. 指定结束标记(推荐交互式场景)
让用户输入完所有配置参数后,输入特定指令(比如done)来终止输入,用户体验更清晰:
import java.util.ArrayList; import java.util.Scanner; public static ArrayList<String> getTrim() { Scanner t = new Scanner(System.in); System.out.println("Enter car trims (input 'done' to finish):"); ArrayList<String> trimList = new ArrayList<>(); while (t.hasNext()) { String input = t.next(); if ("done".equalsIgnoreCase(input)) { break; } // 这里可以加配置参数的格式校验逻辑 trimList.add(input); } t.close(); return trimList; }
如果用户想输入0个参数,直接输入done即可;输入完所有参数后输入done,就能结束输入流程。
2. 读取整行分割(支持批量输入+0参数)
如果用户习惯一次性用空格分隔输入多个参数,直接读取整行再分割,同时支持直接回车返回空列表:
import java.util.ArrayList; import java.util.Scanner; public static ArrayList<String> getTrim() { Scanner t = new Scanner(System.in); System.out.println("Enter car trims (separated by spaces, press enter to finish):"); ArrayList<String> trimList = new ArrayList<>(); String inputLine = t.nextLine(); String trimmedLine = inputLine.trim(); if (!trimmedLine.isEmpty()) { String[] trimItems = trimmedLine.split("\\s+"); // 按任意空白字符分割 for (String item : trimItems) { // 格式校验逻辑在这里加 trimList.add(item); } } t.close(); return trimList; }
这种方式下,用户直接回车就会得到空列表;输入多个参数后回车,所有参数都会被存入列表。
3. 依赖EOF终止输入
如果一定要用hasNext()的EOF触发结束,需要告知用户用快捷键终止,直接回车的话程序会继续等待,但用户可以直接按终止键得到空列表:
import java.util.ArrayList; import java.util.Scanner; public static ArrayList<String> getTrim() { Scanner t = new Scanner(System.in); System.out.println("Enter car trims (press Ctrl+D/Ctrl+Z to finish):"); ArrayList<String> trimList = new ArrayList<>(); while (t.hasNext()) { trimList.add(t.next()); } t.close(); return trimList; }
额外提示
- 你的原始方法返回类型是
ArrayList,建议改成ArrayList<String>,避免类型转换的安全问题。 - 使用完
Scanner后记得调用close()释放资源。
内容的提问来源于stack exchange,提问作者kgil
相关产品推荐
相关产品推荐

