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

读取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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:35:16