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

Java中如何重置Scanner?解决文件重复查询失效问题

问题根源

你的核心问题是绑定到文件的Scanner指针已走到文件末尾,无法自动从头读取。第一次查询Samantha时,input这个Scanner已经读到了文件中对应行的后续位置;第二次循环时,input.hasNextLine()返回false,根本不会进入循环查找Sally。而Scanner.reset()仅重置匹配状态,不会将文件指针移回开头,因此无效。


解决方案

以下提供两种可行方案,同时修复原代码的其他细节问题:

方案1:每次查询前重新初始化文件Scanner

每次用户输入新名字后,重新创建读取文件的Scanner,确保每次都从文件开头查找:

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

public class BabyNames {
    public static void main(String[] args) throws IOException {
        Scanner keyboard = new Scanner(System.in);
        
        System.out.println("这个程序可以查询社会保障局的数据,查看1900年以来名字的流行度。");
        System.out.print("请输入名字:");
        String name = keyboard.nextLine().trim();
        
        while (!"quit".equalsIgnoreCase(name)) {
            // 每次查询重新打开文件,从头读取
            Scanner input = new Scanner(new File("BabyNames.txt"));
            boolean found = false;
            
            while (input.hasNextLine()) {
                String text = input.nextLine();
                String[] words = text.split("\\s+"); // 匹配任意空白,避免多空格问题
                // 精准匹配名字,避免子串误匹配(如Sam匹配Samantha)
                if (words[0].equalsIgnoreCase(name)) {
                    System.out.println("名字\"" + name + "\"的统计数据:");
                    for (int i = 1; i < words.length; i++) {                         
                        System.out.println((1900 + (i-1)*10) + ": " + words[i]);                     
                    }  
                    found = true;
                    break;
                }
            }
            input.close(); // 关闭文件Scanner
            
            if (!found) {
                System.out.println("错误:未找到该名字。");
            }
            
            System.out.println("请输入另一个名字,或输入quit退出。");
            name = keyboard.nextLine().trim();
        }
        keyboard.close();
        System.out.println("程序退出。");
    }
}

方案2:预加载所有数据到内存(推荐)

一次性将文件数据读取到Map中,后续直接从内存查询,效率更高:

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class BabyNames {
    public static void main(String[] args) throws IOException {
        // 预加载所有数据到Map
        Map<String, String[]> nameData = new HashMap<>();
        Scanner input = new Scanner(new File("BabyNames.txt"));
        
        while (input.hasNextLine()) {
            String text = input.nextLine();
            String[] words = text.split("\\s+");
            if (words.length > 0) {
                // 转小写存储,避免大小写敏感
                nameData.put(words[0].toLowerCase(), words);
            }
        }
        input.close();
        
        Scanner keyboard = new Scanner(System.in);
        System.out.println("这个程序可以查询社会保障局的数据,查看1900年以来名字的流行度。");
        System.out.print("请输入名字:");
        String name = keyboard.nextLine().trim();
        
        while (!"quit".equalsIgnoreCase(name)) {
            String[] data = nameData.get(name.toLowerCase());
            if (data != null) {
                System.out.println("名字\"" + name + "\"的统计数据:");
                for (int i = 1; i < data.length; i++) {                         
                    System.out.println((1900 + (i-1)*10) + ": " + data[i]);                     
                }  
            } else {
                System.out.println("错误:未找到该名字。");
            }
            
            System.out.println("请输入另一个名字,或输入quit退出。");
            name = keyboard.nextLine().trim();
        }
        keyboard.close();
        System.out.println("程序退出。");
    }
}

原代码其他细节修复提示

  1. 原text.contains(name)会匹配子串(如输入Sam会匹配Samantha),改用words[0].equalsIgnoreCase(name)实现精准匹配。
  2. 原退出逻辑重复且位置错误,调整为每次获取用户输入后直接判断。
  3. 新增资源关闭操作,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:25:23