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("程序退出。"); } }
原代码其他细节修复提示
- 原
text.contains(name)会匹配子串(如输入Sam会匹配Samantha),改用words[0].equalsIgnoreCase(name)实现精准匹配。 - 原退出逻辑重复且位置错误,调整为每次获取用户输入后直接判断。
- 新增资源关闭操作,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Connor_G
相关产品推荐
相关产品推荐

