读取CSV到Java对象存入ArrayList时遇数组越界异常求助
Hey there, let's break down what's happening and fix this issue step by step.
The Root Cause
The java.lang.ArrayIndexOutOfBoundsException: 6 error means that one of your CSV lines, after splitting by commas, only has 6 or fewer fields (since array indices start at 0, fields[6] is the 7th field). That line is missing the value for cabincrewrequired, so when your code tries to access that index, it throws the exception.
Step-by-Step Fixes
1. Validate Field Count Before Accessing Indices
Add a check to make sure each line has the expected number of fields before you try to access specific indices. This prevents the out-of-bounds error and lets you handle invalid lines gracefully:
while( (line = reader.readLine()) != null) { String[] fields = line.split(","); // Check if we have at least 7 fields (indices 0-6) if (fields.length < 7) { // Handle invalid line: log it, skip it, or throw a more specific error System.err.println("Skipping invalid line: insufficient fields - " + line); continue; } // Rest of your code to parse fields... }
2. Handle CSV Edge Cases (Optional but Recommended)
Using split(",") can break if any of your CSV fields contain commas (e.g., a model name like "Airbus A320,neo"). For robust CSV parsing, consider using a dedicated library like OpenCSV instead of manual splitting. But if you want to stick with manual parsing, you can adjust the split logic or add cleanup for quoted fields.
3. Fix Typos and Redundant Code
You have a couple of issues in your existing code that are unrelated to the exception but should be fixed:
- Typo:
staringPoistionshould bestartingPosition(matches the settersetStartingPosition) - Redundant manufacturer assignments: You're setting the manufacturer three times in a row—only the last one (
Manufacturer.EMBRAER) will stick. You probably want to parse the manufacturer fromfields[3]instead of hardcoding it:// Replace the hardcoded lines with this (assuming Manufacturer is an enum with valueOf) Manufacturer manufacturer = Manufacturer.valueOf(fields[3].trim()); a.setManufacturer(manufacturer);
4. Add Defensive Parsing for Numeric Fields
When parsing seats and cabincrewrequired, wrap the Integer.parseInt calls in try-catch blocks to handle non-numeric values:
int seats; int cabincrewrequired; try { seats = Integer.parseInt(fields[5].trim()); cabincrewrequired = Integer.parseInt(fields[6].trim()); } catch (NumberFormatException e) { System.err.println("Skipping line with invalid numeric values: " + line); continue; }
Updated Code Snippet
Here's how your corrected method might look with these fixes:
public void loadAircraftData(Path p) throws DataLoadingException { try (BufferedReader reader = Files.newBufferedReader(p)) { // Use try-with-resources to auto-close the reader String line = ""; reader.readLine(); // Skip header while( (line = reader.readLine()) != null) { String[] fields = line.split(","); if (fields.length < 7) { System.err.println("Skipping invalid line (insufficient fields): " + line); continue; } String tailcode = fields[0].trim(); String model = fields[1].trim(); String type = fields[2].trim(); String startingPosition = fields[4].trim(); int seats; int cabincrewrequired; try { seats = Integer.parseInt(fields[5].trim()); cabincrewrequired = Integer.parseInt(fields[6].trim()); } catch (NumberFormatException e) { System.err.println("Skipping line with invalid numbers: " + line); continue; } // Parse manufacturer (fix this if your enum uses different names than CSV values) Manufacturer manufacturer; try { manufacturer = Manufacturer.valueOf(fields[3].trim().toUpperCase()); } catch (IllegalArgumentException e) { System.err.println("Skipping line with unknown manufacturer: " + fields[3]); continue; } Aircraft a = new Aircraft(); a.setTailCode(tailcode); a.setModel(model); a.setTypeCode(type); a.setManufacturer(manufacturer); a.setStartingPosition(startingPosition); a.setSeats(seats); a.setCabinCrewRequired(cabincrewrequired); aircraft.add(a); } } catch (Exception e) { throw new DataLoadingException("加载数据失败", e); } }
Key Takeaways
- Always validate input data before accessing array indices to avoid out-of-bounds errors
- Use try-with-resources for auto-closing resources like
BufferedReader - Handle edge cases like invalid numeric values or unknown enum values gracefully
- For production code, prefer a dedicated CSV library over manual splitting to handle complex CSV formats
内容的提问来源于stack exchange,提问作者Jiayao Wang

