为何我的Java代码抛出IllegalStateException?求问题排查与修复
Let's break down the problems in your code and fix them step by step:
Key Problems Identified
1. Premature Scanner Closure Causing IllegalStateException
In your inputCity method, you're calling in.close() inside the while loop. This closes the System.in input stream immediately after the first iteration. Any subsequent attempts to read from System.in (in inputDistance or main) will throw an IllegalStateException because the stream is already closed. Plus, this stops you from reading all the city names in the first place.
2. Broken City Name Reading Logic
Your current code reads a string with in.next() to check if it's "###", then calls in.next() again to add to the city list. This skips the first city name! For example, if you input Hagzou Hugzou Jigxng ###, the first in.next() grabs Hagzou, checks it's not "###", then add(in.next()) grabs Hugzou—so Hagzou never gets added to your list, making your distance matrix indices misaligned.
3. Redundant Index Lookup
The loops in getDistance are unnecessary. You can directly use city.indexOf(a) to get the index of a city, no need to loop through the entire list manually.
Corrected Code
Here's the fixed version with comments explaining the changes:
package findmiles; import java.util.ArrayList; import java.util.Scanner; public class Findmiles { private ArrayList<String> city = new ArrayList<String>(); private long[][] distance; // Use a single Scanner instance across the class to avoid closing System.in early private Scanner in = new Scanner(System.in); public void inputCity() { String currentInput; // Read input first, check if it's "###", then add to list if not while (!(currentInput = in.next()).equals("###")) { city.add(currentInput); } } public void inputDistance() { int cityCount = city.size(); distance = new long[cityCount][cityCount]; for (int i = 0; i < cityCount; i++) { for (int j = 0; j < cityCount; j++) { distance[i][j] = in.nextLong(); } } } public long getDistance(String cityA, String cityB) { // Directly get indices using indexOf() - clean and efficient int indexA = city.indexOf(cityA); int indexB = city.indexOf(cityB); // Optional: Add a check here if indexA/indexB is -1 (city not found) return distance[indexA][indexB]; } public static void main(String[] args) { Findmiles distanceCalculator = new Findmiles(); distanceCalculator.inputCity(); distanceCalculator.inputDistance(); String startCity = distanceCalculator.in.next(); String endCity = distanceCalculator.in.next(); System.out.println(distanceCalculator.getDistance(startCity, endCity)); // Close the Scanner only after all input is read distanceCalculator.in.close(); } }
What Changed?
- Single Scanner Instance: We create one Scanner for the entire class, so we don't accidentally close
System.inearly. We only close it at the very end of the program. - Fixed City Reading: We store the input string in a variable first, so we don't skip any city names when checking for "###".
- Simplified Index Lookup: Removed the redundant loops and used
indexOf()directly to get city indices, making the code cleaner and faster.
Now when you run your test input:Hagzou Hugzou Jigxng ### 0 1108 708 1108 0 994 708 994 0 Hagzou Jigxng
You'll get the expected output of 708.
内容的提问来源于stack exchange,提问作者Huglight

