Scanner获取输入时抛出NoSuchElementException异常的排查
修复Scanner导致的NoSuchElementException问题
嘿,这个异常的根源其实很明确——你重复创建并关闭Scanner,导致System.in输入流被提前关闭了!
问题原因详解
当你在main方法的循环里调用myObj.close()时,Scanner会自动关闭它关联的底层输入流(也就是System.in)。一旦System.in被关闭,后续不管你在binarySearch方法里新建多少个Scanner实例,都没法再从控制台读取输入了,这就直接抛出了NoSuchElementException。
修复方案
我们只需要复用同一个Scanner实例,不要随便关闭它,把它作为参数传递给binarySearch方法即可:
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.ArrayList; import java.util.Scanner; public class Rater { public static void main(String[] args) throws Exception { File file = new File("E:\\topmovies.txt"); BufferedReader br = new BufferedReader(new FileReader(file)); String st; ArrayList<String> movList = new ArrayList<String>(); while ((st = br.readLine()) != null) { movList.add(st); } br.close(); // 只创建一次Scanner,复用整个程序生命周期 Scanner myObj = new Scanner(System.in); while (true) { System.out.println("Enter a movie to add."); String userName = myObj.nextLine(); // 不要在这里关闭Scanner! int index = binarySearch(movList, userName, 0, movList.size() - 1, myObj); movList.add(index, userName); } // 如果需要程序结束时关闭,可以在这里加myObj.close(); } // 把Scanner作为参数传入,不再内部创建 static int binarySearch(ArrayList<String> a, String item, int low, int high, Scanner scanner) { if (high <= low) { System.out.println("Did you like " + item + " more than " + a.get(low) + "?"); String answer2 = scanner.nextLine().toLowerCase(); if (answer2.equals("yes")) { return low + 1; } return low; } int mid = (low + high) / 2; if (item.equals(a.get(mid))) { // 这里顺便帮你把==改成equals,字符串比较要用equals return mid + 1; } System.out.println("Did you like " + item + " more than " + a.get(mid) + "?"); String answer2 = scanner.nextLine().toLowerCase(); if (answer2.equals("yes")) { return binarySearch(a, item, mid + 1, high, scanner); } return binarySearch(a, item, low, mid - 1, scanner); } }
关键改动点
- 在main方法中只初始化一次
Scanner,不再每次循环创建和关闭 - 将
Scanner作为参数传递给binarySearch方法,复用同一个实例 - 移除了
binarySearch内部所有创建和关闭Scanner的代码 - 顺便修复了字符串比较的小问题:把
item == a.get(mid)改成了item.equals(a.get(mid))(字符串比较不能用==,否则会比较对象地址而非内容)
内容的提问来源于stack exchange,提问作者Jason Matthews
相关产品推荐
相关产品推荐

