You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    }
}

关键改动点

  1. 在main方法中只初始化一次Scanner,不再每次循环创建和关闭
  2. 将Scanner作为参数传递给binarySearch方法,复用同一个实例
  3. 移除了binarySearch内部所有创建和关闭Scanner的代码
  4. 顺便修复了字符串比较的小问题:把item == a.get(mid)改成了item.equals(a.get(mid))(字符串比较不能用==,否则会比较对象地址而非内容)

内容的提问来源于stack exchange,提问作者Jason Matthews

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:56:36