如何修正Java while循环以正确读取食谱生成对象列表?
解决Java读取食谱文件时内层循环的逻辑问题
问题背景
作为刚学几周Java的初学者,在完成赫尔辛基Java Moocfi最终练习时,编写代码读取recipes.txt文件生成包含名称、烹饪时间、食材列表的Recipe对象列表,遇到两个问题:
- 第一个食谱只能读取隔一个食材
- 处理第二个食谱时触发"no line found"错误
示例文件格式
Pancake dough 60 milk egg flour sugar salt butter Meatballs 20 ground meat egg breadcrumbs Tofu rolls 30 tofu rice water carrot cucumber avocado wasabi
现有问题代码
try (Scanner scanner = new Scanner(Paths.get("recipes.txt"))) { while (scanner.hasNextLine()) { name = scanner.nextLine(); cookingTime = Integer.valueOf(scanner.nextLine()); // while (!(scanner.nextLine().isEmpty())) { // ingredient = scanner.nextLine(); // ingredients.add(ingredient); // } while (true) { checkEmpty = scanner.nextLine(); if (checkEmpty.isEmpty()) { break; } else { ingredient = checkEmpty; } ingredients.add(ingredient); } recipes.add(new Recipe(name, cookingTime, ingredients)); } } catch (Exception e) { System.out.println("Error: " + e.getMessage()); }
问题分析与解决方案
原代码的问题点
- 无行判断缺失:内层循环直接调用
scanner.nextLine(),当文件最后一个食谱没有结尾空行时,会触发NoSuchElementException(即"no line found"错误)。 - 重复读取行(注释掉的循环):注释的循环里每次判断时读一行,添加食材又读一行,导致每两个食材只保留一个,出现"隔一个读取"的情况。
修正后的内层循环逻辑
核心是先判断是否还有行可读,再读取,且每行只读取一次:
// 每次处理新食谱前要清空或新建食材列表,避免食材累积到下一个食谱 ingredients.clear(); while (scanner.hasNextLine()) { String line = scanner.nextLine(); if (line.isEmpty()) { break; // 空行表示当前食谱的食材列表结束 } ingredients.add(line); }
完整修正后的关键代码片段
try (Scanner scanner = new Scanner(Paths.get("recipes.txt"))) { while (scanner.hasNextLine()) { String name = scanner.nextLine(); int cookingTime = Integer.valueOf(scanner.nextLine()); List<String> ingredients = new ArrayList<>(); // 每次循环新建列表,避免食材累积 while (scanner.hasNextLine()) { String line = scanner.nextLine(); if (line.isEmpty()) { break; } ingredients.add(line); } recipes.add(new Recipe(name, cookingTime, ingredients)); } } catch (Exception e) { System.out.println("Error: " + e.getMessage()); }
额外注意点
- 每次处理新食谱时,要新建或清空食材列表,否则前一个食谱的食材会被添加到下一个食谱中。
- 确保
Recipe类的构造函数能正确接收名称、烹饪时间和食材列表参数。
内容的提问来源于stack exchange,提问作者Felix_is_coding
相关产品推荐
相关产品推荐

