Java读取CSV添加第8列时触发ArrayIndexOutOfBoundsException:7异常
ArrayIndexOutOfBoundsException:7的问题 咱们来拆解一下为啥明明你的CSV文件有8列,添加date_sold.add(cols[7]);后却抛出了ArrayIndexOutOfBoundsException: 7异常——核心原因是你读取到的某一行数据,经过split(",")分割后得到的数组长度小于8,和while循环本身没有直接关系,具体可能有这几个场景:
可能的原因
存在不完整的行或空行:
比如CSV文件的最后一行是空的,或者某一行的字段被遗漏了(比如少写了一个逗号分隔的字段)。当readLine()读到这样的行时,split(",")得到的数组长度会小于8,这时候访问cols[7]自然会越界。举个例子,空行split后会得到一个长度为1的数组[""],完全够不到索引7。字段包含未转义的逗号:
CSV规范里允许字段包含逗号,但需要用双引号包裹(比如"123 Main St, Apt 4B")。但你的代码用split(",")会直接把这个逗号当成字段分隔符,导致整行分割后的字段数混乱——可能某一行被拆成了更多或更少的字段,进而导致索引7不存在。
解决方案
1. 先排查问题行
在循环里添加判断逻辑,打印出不符合要求的行,快速定位问题:
while ((line = br.readLine()) != null) { wholefile.add(line); String[] cols = line.split(","); // 检查字段数是否符合预期 if (cols.length < 8) { System.err.println("发现字段数不足的行:" + line); System.err.println("当前分割后的字段数:" + cols.length); // 可以选择跳过该行,或者做错误处理 continue; } // 正常添加数据到各个List id.add(cols[0]); property_address.add(cols[1]); first_name.add(cols[2]); last_name.add(cols[3]); email.add(cols[4]); owner_address.add(cols[5]); price.add(cols[6]); date_sold.add(cols[7]); }
运行这段代码后,控制台会输出有问题的行内容,你就能知道是哪一行数据出了问题。
2. 使用专业的CSV解析库
手动用split(",")处理CSV是非常脆弱的,无法应对带逗号、引号、换行的复杂字段。推荐使用成熟的CSV解析库,比如OpenCSV或Apache Commons CSV,它们会严格遵循CSV规范解析数据。
以OpenCSV为例,简单实现代码:
// 先引入OpenCSV依赖(Maven): // <dependency> // <groupId>com.opencsv</groupId> // <artifactId>opencsv</artifactId> // <version>5.6</version> // </dependency> import com.opencsv.CSVReader; import java.io.FileReader; import java.util.ArrayList; import java.util.List; public class CsvReader { public static void main(String[] args) { List<String> id = new ArrayList<>(); List<String> property_address = new ArrayList<>(); List<String> first_name = new ArrayList<>(); List<String> last_name = new ArrayList<>(); List<String> email = new ArrayList<>(); List<String> owner_address = new ArrayList<>(); List<String> price = new ArrayList<>(); List<String> date_sold = new ArrayList<>(); try (CSVReader reader = new CSVReader(new FileReader("./data.csv"))) { String[] nextLine; while ((nextLine = reader.readNext()) != null) { // nextLine是已经正确解析的字段数组 if (nextLine.length == 8) { id.add(nextLine[0]); property_address.add(nextLine[1]); first_name.add(nextLine[2]); last_name.add(nextLine[3]); email.add(nextLine[4]); owner_address.add(nextLine[5]); price.add(nextLine[6]); date_sold.add(nextLine[7]); } else { System.err.println("字段数不符的行:" + String.join(",", nextLine)); } } } catch (Exception e) { e.printStackTrace(); } } }
这类库会自动处理带引号的字段、转义字符等场景,彻底避免手动分割带来的问题。
内容的提问来源于stack exchange,提问作者Kabira Suleman

