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

ArrayIndexOutOfBoundsException异常排查:CSV转ArrayList报错

问题:读取CSV文件存入ArrayList时抛出ArrayIndexOutOfBoundsException异常

尝试读取CSV文件(内容为C,John,Goh,0031)并将数据存入ArrayList,运行时持续抛出异常:ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 1。相关代码如下:

核心处理方法代码

public static boolean processNewData(ArrayList<Student> studList, String filename) {
    File infile = new File(filename);
    Scanner reader = null;

    boolean addStudent = true;
    boolean success = false;

    try {
        reader = new Scanner(infile);

        while (reader.hasNextLine()) {
            String row = reader.nextLine();
            String[] data = row.split(",");
            
            if (studList.size() == 0) {
                addStudent = true;
            } else if (studList.size() > 0) {
                // Check if student number exist in the student arraylist
                for (Student s : studList) {
                    if (s.getStudNo() == Long.parseLong(data[3])) {
                        addStudent = false;
                        throw new StudentException("Student Number Exist....");
                    } else {
                        addStudent = true;
                        continue;
                    }
                }
            }

            if (addStudent == true) {
                if (data[0].compareToIgnoreCase("C") == 0) {
                    Student_Course s1 = new Student_Course(
                                            data[1], data[2], 
                                            Long.parseLong(data[3])
                                        );
                    success = true;
                    studList.add(s1);
                } else if (data[0].compareToIgnoreCase("R") == 0) {
                    Student_Research s1 = new Student_Research(
                                            data[1], data[2], 
                                            Long.parseLong(data[3])
                                        );
                    success = true;
                    studList.add(s1);
                } else {
                    // If the enrolement is neither C or R, print the student ID and show the enrolement type
                    // Continue to add the rest
                    System.out.println();
                    System.out.println("Student Number: " + data[3] + " from file with invalid type - " + data[0]);
                    success = false;
                    continue;
                }
            }
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (StudentException e) {
        e.printStackTrace();
    } finally {
        if (reader != null) {
            reader.close();
        }
    }
    return success;
}

Student_Course类代码

public class Student_Course extends Student {
    private Unit_Course unitCourse;
    private String enrolementType;

    public Student_Course(String fName, String lName, long studNo) {
        super(fName, lName, studNo);
        enrolementType = "C";
    }
}

异常原因分析

这个异常明确说明:你尝试访问数组下标3,但数组实际长度只有1。这意味着某一行CSV数据经过split(",")分割后,只得到了1个元素,而非预期的4个字段。

最可能的触发场景:

  • CSV文件中存在空行:空行调用split(",")会返回长度为1的数组(元素为空字符串)。
  • 存在格式错误的行:比如某一行没有使用逗号分隔,整行作为一个元素存入数组。

除此之外,代码还有几个潜在问题会导致逻辑异常:

  1. 重复学生检查逻辑错误:只要找到一个不重复的学生,就会把addStudent设为true并跳过后续检查。如果列表中前面的学生不重复,但后面有重复的,会漏掉重复判断,导致重复学生被添加。
  2. 抛出StudentException后直接终止循环:后续行无法继续处理,中断整个文件读取流程。
  3. 未妥善关闭Scanner资源:可能导致资源泄漏。

修复方案

1. 过滤空行与无效格式行

在分割前先处理空行,分割后检查数组长度是否符合预期,不符合则跳过并提示:

while (reader.hasNextLine()) {
    String row = reader.nextLine().trim(); // 去除行首尾空白字符
    if (row.isEmpty()) {
        continue; // 跳过空行
    }
    String[] data = row.split(",");
    if (data.length != 4) {
        System.out.println("跳过格式无效的行:" + row);
        continue;
    }
    // 后续业务逻辑...
}

2. 修正重复学生检查逻辑

先默认允许添加,找到重复项后标记为不允许并跳出循环,避免中途覆盖标记:

addStudent = true; // 默认允许添加
if (!studList.isEmpty()) {
    for (Student s : studList) {
        if (s.getStudNo() == Long.parseLong(data[3])) {
            addStudent = false;
            System.out.println("学生编号已存在:" + data[3]);
            break; // 找到重复项后立即退出循环,无需继续检查
        }
    }
}

如果不需要中断整个流程,建议移除throw new StudentException,改为控制台提示即可。

3. 使用try-with-resources自动关闭资源

替换手动关闭Scanner的逻辑,确保资源自动释放:

try (Scanner reader = new Scanner(infile)) { // try-with-resources会自动关闭资源
    while (reader.hasNextLine()) {
        // 循环逻辑...
    }
} catch (FileNotFoundException e) {
    System.out.println("文件未找到:" + filename);
    return false;
} catch (StudentException e) {
    e.printStackTrace();
}

4. 处理学号前导零(可选)

Long.parseLong("0031")会将其转换为数值31,丢失前导零。如果需要保留前导零的字符串形式,需要修改Student类的学号字段类型为String,并调整相关方法的参数与返回值。


内容的提问来源于stack exchange,提问作者Aloysious Kok

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:30:49