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

Java程序抛出NoSuchElementException异常,求AP计算机科学A教师协助排查

问题:Java机票预订系统抛出NoSuchElementException异常

异常信息

Exception in thread "main" java.util.NoSuchElementException
    at java.base/java.util.Scanner.throwFor(Scanner.java:937)
    at java.base/java.util.Scanner.next(Scanner.java:1478)
    at Main.initializePlanes(Main.java:59)
    at Main.main(Main.java:83)
exit status 1

背景说明

我正在开发一个机票预订系统:

  • Planes.out存储飞机变量列表
  • Moderators.in存储管理员密码

运行代码时触发上述异常,尝试关闭所有FileWriter无效,查阅资料未找到解决方案,需要排查修复。

完整代码

import java.util.*;
import java.io.*;
class Main {
  public static void planeMaker(ArrayList<Plane> planes) throws IOException {
    boolean tvs;
    Scanner input = new Scanner(System.in);
    System.out.println("PLANE MAKER\n");
    System.out.println("\nEnter the name:\t");
    String name = input.nextLine();
    System.out.println("\nEnter the destination:\t"); 
    String destination = input.nextLine();
    System.out.println("\nEnter the depart location:\t"); 
    String departLocation = input.nextLine();
    System.out.println("\nEnter the amount of seats:\t"); 
    int seats = input.nextInt();
    System.out.println("\nEnter the amount of rows:\t"); 
    int rows = input.nextInt();
    System.out.println("\nEnter the amount of columns:\t"); 
    int columns = input.nextInt();
    System.out.println("\nAre there tvs?:\t"); 
    String buffer = input.nextLine();
    String qr = input.nextLine();
    if(qr.equalsIgnoreCase("yes")) {
      tvs = true;
    } else {
      tvs = false;
    }
    System.out.println("\nEnter the seat cost:\t"); 
    int seatCost = input.nextInt();
    System.out.println("\nEnter the boarding time (7:30 -> 730):\t"); 
    int boardingTime = input.nextInt();
    System.out.println("\nEnter the flight duration (in mins):\t"); 
    int flightDuration = input.nextInt();
    System.out.println("\nEnter the day of the month of takeoff:\t"); 
    int dayOfTheMonth = input.nextInt();
    FileWriter fw = new FileWriter("Planes.out");
    PrintWriter output = new PrintWriter(fw);
    output.print(name + " " + destination + " " + departLocation + " " + seats + " " + rows + " " + columns + " "+ tvs+ " "+ seatCost+" "+boardingTime+" "+flightDuration+" "+dayOfTheMonth);
  }
  public static void modIn(ArrayList<Plane> planes) throws IOException {
    Scanner input = new Scanner(System.in);
    System.out.println("What would you like to do?\n");
    System.out.println("\n\t1.) Create a Plane\n\t2.) Change a flight time");
    int qeu = input.nextInt();
    if(qeu == 1) {
      planeMaker(planes);
    } else if(qeu == 2){
      changeBoardingTime(planes);
    }
  }
  public static ArrayList<Plane> initializePlanes() {
    Scanner initialize = new Scanner("Planes.out");
    String name, destination, departLocation;
    int seats, rows, columns, seatCost, boardingTime, flightDuration, dayOfTheMonth;
    boolean tvs;
    ArrayList<Plane> plan = new ArrayList<Plane>();
    while(initialize.hasNext()) {
      name = initialize.next();
      destination = initialize.next();
      departLocation = initialize.next();
      seats = initialize.nextInt();
      rows = initialize.nextInt();
      columns = initialize.nextInt();
      tvs = initialize.nextBoolean();
      seatCost = initialize.nextInt();
      boardingTime = initialize.nextInt();
      flightDuration = initialize.nextInt();
      dayOfTheMonth = initialize.nextInt();
      plan.add(new Plane(name,destination,departLocation,seats,rows,columns,tvs,seatCost, boardingTime, flightDuration, dayOfTheMonth));
    }
    initialize.close();
    return plan;
  }
  public static void changeBoardingTime(ArrayList<Plane> planes) {
    System.out.println("What plane would you like to change the boarding time of?");
    System.out.println("PLANES:");
    for(int i = 0; i < planes.size(); i++) {
      System.out.println("\t"+planes.get(i).getName());
    }
  }
  public static void main(String[] args) throws IOException{
    ArrayList<Plane> planes = new ArrayList<Plane>();
    planes = initializePlanes();
    boolean qr = false;
    FileWriter fw = new FileWriter("Output1.out");
    PrintWriter output = new PrintWriter(fw);
    Scanner input = new Scanner(System.in);
    System.out.println("Hello, welcome to Airway Airline reservation system.\nPlease enter what you would like to do next: ");
    System.out.println("\t1.) Book a seat\n\t2.) View your reservation\n\t3.) Sign into moderator");
    int question = input.nextInt();
    if(question == 1) {
      
    } else if(question == 2) {
      
    } else if(question == 3) {
      Scanner modPass = new Scanner(new File("Moderators.in"));
      System.out.println("\nPlease enter your moderator password: ");
      String buffer = input.nextLine();
      String modAsk = input.nextLine();
      while(modPass.hasNext()) {
        if(modPass.next().equals(modAsk)) {
          modIn(planes);
          qr = true;
        }
      }
      if(qr == false) {
          System.out.println("YOU ARE NOT A MODERATOR!!!");
          System.exit(0);
      }
    }
  }
}

问题排查与修复方案

1. 核心异常原因

异常触发在initializePlanes方法的name = initialize.next();行,问题出在Scanner初始化错误:

Scanner initialize = new Scanner("Planes.out");

这里传入的是字符串"Planes.out",Scanner会把该字符串当成输入源解析,而非读取对应文件的内容。当尝试读取下一个元素时,字符串中没有足够的分隔数据,直接抛出NoSuchElementException。

2. 具体修复步骤

(1)修正文件读取逻辑

将initializePlanes方法改为正确读取文件,同时处理文件不存在的情况:

public static ArrayList<Plane> initializePlanes() {
    ArrayList<Plane> plan = new ArrayList<Plane>();
    // 使用try-with-resources自动关闭资源
    try (Scanner initialize = new Scanner(new File("Planes.out"))) {
        String name, destination, departLocation;
        int seats, rows, columns, seatCost, boardingTime, flightDuration, dayOfTheMonth;
        boolean tvs;
        
        while(initialize.hasNext()) {
            name = initialize.next();
            destination = initialize.next();
            departLocation = initialize.next();
            seats = initialize.nextInt();
            rows = initialize.nextInt();
            columns = initialize.nextInt();
            tvs = initialize.nextBoolean();
            seatCost = initialize.nextInt();
            boardingTime = initialize.nextInt();
            flightDuration = initialize.nextInt();
            dayOfTheMonth = initialize.nextInt();
            plan.add(new Plane(name,destination,departLocation,seats,rows,columns,tvs,seatCost, boardingTime, flightDuration, dayOfTheMonth));
        }
    } catch (FileNotFoundException e) {
        System.out.println("Planes.out文件不存在,初始化空飞机列表");
    }
    return plan;
}

(2)修复文件写入覆盖问题

当前planeMaker方法每次写入会覆盖Planes.out,改为追加模式并添加换行:

// 第二个参数true表示追加写入
FileWriter fw = new FileWriter("Planes.out", true);
PrintWriter output = new PrintWriter(fw);
// 每个飞机数据结尾加换行,避免所有数据挤在一行
output.println(name + " " + destination + " " + departLocation + " " + seats + " " + rows + " " + columns + " "+ tvs+ " "+ seatCost+" "+boardingTime+" "+flightDuration+" "+dayOfTheMonth);
output.close(); // 确保数据写入文件

(3)解决Scanner换行残留问题

使用nextInt()后输入流会残留换行符,导致后续nextLine()读取空字符串,需要手动消耗:

  • 在planeMaker方法中:
System.out.println("\nEnter the amount of columns:\t"); 
int columns = input.nextInt();
input.nextLine(); // 消耗换行符
System.out.println("\nAre there tvs?:\t"); 
String qr = input.nextLine(); // 直接读取输入,无需额外buffer
  • 在main方法中:
int question = input.nextInt();
input.nextLine(); // 消耗换行符

3. 其他优化建议

  • 确保Plane类存在匹配的构造方法,否则代码无法编译
  • Moderators.in的读取也建议使用try-with-resources,避免资源泄漏
  • 所有文件操作补充异常处理,防止未捕获的IOException导致程序崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:57:03