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
相关产品推荐
相关产品推荐

