Java中搭配Scanner使用的.contains()方法不生效是什么原因?
问题根源
你的代码核心问题出在Scanner的遍历特性上:
- 你只初始化了一次电话簿的Scanner,当第一个待查姓名走完内层while循环后,Scanner的读取指针已经移动到了电话簿文件末尾,
scanner.hasNextLine()会永久返回false - 后续剩下的499个待查姓名根本不会进入内层匹配逻辑,最终统计出来的匹配数自然只有1
解决方案
方案1:简单修复(不推荐,效率极低)
如果坚持要每次查询都遍历整个电话簿,每次查询前都重新生成电话簿的Scanner即可,但500次遍历百万行文件会导致耗时极高:
// 原main方法的循环逻辑修改为: for (int i = 0; i < Objects.requireNonNull(names).length; i++) { // 每次匹配新名字都重新打开电话簿文件,让读取指针回到文件开头 try (Scanner tempScanner = new Scanner(directoryFile)) { while (tempScanner.hasNextLine()) { if (tempScanner.nextLine().contains(names[i])) { count++; break; } } } catch (FileNotFoundException e) { e.printStackTrace(); } }
方案2:优化实现(推荐,效率提升数百倍)
先把电话簿的所有内容一次性读入HashSet,再遍历待查列表直接判断存在性,仅需遍历一次电话簿:
// 需先导入java.util.HashSet public static void main(String[] args) { File findFile = new File(NAME_PATH); File directoryFile = new File(PHONEBOOK_PATH); String[] names = namesList(findFile); int count = 0; System.out.println("Start searching..."); long timeStart = System.currentTimeMillis(); // 一次性读取所有电话簿内容存入集合 HashSet<String> phoneBookLines = new HashSet<>(); try (Scanner scanner = new Scanner(directoryFile)) { while (scanner.hasNextLine()) { phoneBookLines.add(scanner.nextLine()); } } catch (FileNotFoundException e) { System.out.printf("File not found: %s", PHONEBOOK_PATH); return; } // 遍历待查姓名直接匹配 for (String name : Objects.requireNonNull(names)) { // 如果需要精确匹配,可先拆分电话簿行提取姓名单独存储,直接调用contains判断即可 if (phoneBookLines.stream().anyMatch(line -> line.contains(name))) { count++; } } long timeEnd = System.currentTimeMillis(); System.out.print("Found " + count + " / " + names.length + " entries. " + timeDifference(timeStart, timeEnd)); }
内容的提问来源于stack exchange,提问作者Jeremiahtaylor2017
相关产品推荐
相关产品推荐

