读取CSV至ArrayList遇数组越界异常,需实现行数据校验
解决CSV读取到ArrayList时的数组越界+数据校验问题
嘿,我来帮你搞定这个问题!你遇到的Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException,大概率是解析CSV行时,拆分后的字段数组长度和你预期的学生属性数不匹配导致的——比如你以为每行有4个字段,但某行实际只有3个(信息缺失)或者多了2个(冗余),直接按固定索引取值就会触发越界。结合你要校验数据完整性的需求,咱们一步步来解决:
首先明确核心逻辑
要同时解决数组越界和数据校验,关键是先校验再取值:
- 先检查每行拆分后的字段数量是否和
MyStudent的属性数一致 - 再检查每个字段是否非空(避免空字符串或纯空格的无效数据)
- 只有通过所有校验,才创建
MyStudent对象加入集合,否则直接丢弃该行
示例代码实现(纯JDK方式)
假设你的MyStudent类有id、name、age、major四个属性,下面是完整的读取+校验逻辑:
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; public class MyStudent { private String id; private String name; private int age; private String major; // 构造方法、Getter/Setter按需实现 public MyStudent(String id, String name, int age, String major) { this.id = id; this.name = name; this.age = age; this.major = major; } public static void main(String[] args) { ArrayList<MyStudent> studentList = new ArrayList<>(); String csvPath = "your_students.csv"; final int EXPECTED_FIELDS = 4; // 和MyStudent的属性数对应 try (BufferedReader br = new BufferedReader(new FileReader(csvPath))) { String line; br.readLine(); // 跳过CSV表头(没有表头就注释这行) while ((line = br.readLine()) != null) { // 拆分CSV行(注意:如果字段包含逗号,这个方法会失效,后面会说解决方案) String[] fields = line.split(","); // 校验1:字段数是否匹配,不匹配直接丢弃 if (fields.length != EXPECTED_FIELDS) { System.out.println("丢弃字段数异常的行:" + line); continue; } // 校验2:所有字段是否非空(trim去掉前后空格,避免纯空格的无效数据) boolean hasEmptyField = false; for (String field : fields) { if (field.trim().isEmpty()) { hasEmptyField = true; break; } } if (hasEmptyField) { System.out.println("丢弃含空字段的行:" + line); continue; } // 安全转换数据(比如年龄转int,处理格式错误) try { int age = Integer.parseInt(fields[2].trim()); MyStudent student = new MyStudent( fields[0].trim(), fields[1].trim(), age, fields[3].trim() ); studentList.add(student); } catch (NumberFormatException e) { System.out.println("丢弃年龄格式错误的行:" + line); continue; } } } catch (IOException e) { System.err.println("读取CSV文件出错:" + e.getMessage()); e.printStackTrace(); } // 验证结果 System.out.println("\n成功读取的有效学生数据:"); studentList.forEach(s -> System.out.println(s.getId() + " | " + s.getName() + " | " + s.getAge() + " | " + s.getMajor())); } // 这里补充Getter方法,方便打印结果 public String getId() { return id; } public String getName() { return name; } public int getAge() { return age; } public String getMajor() { return major; } }
处理复杂CSV场景(字段含逗号)
如果你的CSV里有带逗号的字段(比如"Doe, Jane",22,Mathematics),用split(",")会把名字拆成两个字段,导致字段数校验失败。这种情况建议用专业的CSV解析库,比如OpenCSV,它能自动处理带引号的字段:
依赖引入(Maven)
<dependency> <groupId>com.opencsv</groupId> <artifactId>opencsv</artifactId> <version>5.6</version> </dependency>
OpenCSV版本的核心代码
import com.opencsv.CSVReader; import com.opencsv.exceptions.CsvValidationException; // ... 其他代码 try (CSVReader reader = new CSVReader(new FileReader(csvPath))) { String[] nextLine; reader.readNext(); // 跳过表头 while ((nextLine = reader.readNext()) != null) { if (nextLine.length != EXPECTED_FIELDS) { System.out.println("丢弃字段数异常的行:" + String.join(",", nextLine)); continue; } // 后续的空字段校验、数据转换逻辑和之前一致 // ... } } catch (CsvValidationException | IOException e) { e.printStackTrace(); }
这样就能彻底避免因为CSV格式复杂导致的数组越界问题,同时保证数据校验的准确性。
内容的提问来源于stack exchange,提问作者sadist45
相关产品推荐
相关产品推荐

