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

如何修正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());
}

问题分析与解决方案

原代码的问题点

  1. 无行判断缺失:内层循环直接调用scanner.nextLine(),当文件最后一个食谱没有结尾空行时,会触发NoSuchElementException(即"no line found"错误)。
  2. 重复读取行(注释掉的循环):注释的循环里每次判断时读一行,添加食材又读一行,导致每两个食材只保留一个,出现"隔一个读取"的情况。

修正后的内层循环逻辑

核心是先判断是否还有行可读,再读取,且每行只读取一次:

// 每次处理新食谱前要清空或新建食材列表,避免食材累积到下一个食谱
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 22:46:15