You need to enable JavaScript to run this app. 如何使用Java的Apache Commons CSV库移除CSV文件重复列
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Java的Apache Commons CSV库移除CSV文件重复列

用Apache Commons CSV实现CSV重复列移除的方案

首先明确核心前提:
Apache Commons CSV的核心定位是CSV格式的解析与输出,常被用来做重复行去重,但没有内置的"重复列自动移除/跳过"的开箱即用能力。碰到带重复表头的CSV文件时,默认配置下甚至会因为规则限制直接抛出解析异常。要实现重复列的跳过,只需要结合库的原生API做少量自定义逻辑适配即可,实现成本很低。

核心实现逻辑

重复列的判定完全基于表头匹配:遍历解析出的所有原始表头,仅保留每个表头第一次出现的位置,后续同名列对应的列全部跳过。
这个逻辑和你现有代码的规则是完全兼容的:比如你开了忽略表头大小写、自动trim表头前后空格的配置,重复列的判定会自动套用这些规则,不需要额外调整。

步骤拆解

  1. 调整解析配置,允许重复表头存在
    默认配置下,Commons CSV 检测到重复表头名会直接抛出 IllegalArgumentException,必须手动开启重复表头允许,才能拿到完整的原始表头列表。
  2. 基于原始表头计算需要保留的列索引
    逐一遍历所有解析到的表头,记录已出现过的表头名称,碰到第一次出现的列就把索引加入保留列表,碰到重复的列就直接标记跳过。
  3. 逐行读取数据时,仅按照保留的索引取值
    不要直接用record.get("列名")的方式取值——存在重复列时,这个方法只会返回最后一个同名列的字段值,完全没法控制保留哪一个重复列,基于索引取值是最可靠的方式。

适配你现有代码的完整实现

// 用try-with-resources自动关闭资源,避免IO泄漏
try (
        Reader reader = Files.newBufferedReader(Paths.get("user.csv"));
        CSVParser parser = CSVFormat.DEFAULT
                .withFirstRecordAsHeader()
                .withIgnoreHeaderCase()
                .withTrim()
                // 关键配置:允许重复表头存在,否则解析会直接报错
                .withAllowDuplicateHeaderNames()
                .parse(reader);
) {
    // 获取全部原始表头,计算需要保留的列索引
    Set<String> existingHeaders = new HashSet<>();
    List<Integer> keepColumnIndex = new ArrayList<>();
    List<String> rawHeaderList = parser.getHeaderNames();

    for (int i = 0; i < rawHeaderList.size(); i++) {
        String currentHeader = rawHeaderList.get(i);
        // 仅保留第一次出现的列
        if (!existingHeaders.contains(currentHeader)) {
            existingHeaders.add(currentHeader);
            keepColumnIndex.add(i);
        }
    }

    // 逐行读取数据
    for (CSVRecord record : parser) {
        System.out.println("Record #: " + record.getRecordNumber());
        // 按保留的索引读取列内容,自动跳过重复列
        for (Integer index : keepColumnIndex) {
            String headerName = rawHeaderList.get(index);
            String cellValue = record.get(index);
            System.out.println(headerName + ": " + cellValue);
        }
        System.out.println("---");
    }
}

效果验证

针对你给出的表头示例 ID Name Email Email,上述逻辑会自动识别出索引位置3的Email列是重复项,只保留索引0(ID)、1(Name)、2(Email)三个列的内容,第二个重复的Email列不会被读取。

注意:如果你的业务需要保留最后一个出现的重复列、或者给重复列重命名(比如Email/Email1),只需要调整保留列索引的判定逻辑即可,不需要改动整体的解析流程。

版本兼容说明:withAllowDuplicateHeaderNames 是Commons CSV 1.8版本新增的配置,如果使用的是更早的旧版本,可先关闭withFirstRecordAsHeader()配置,手动读取第一行原始数据作为表头,再逐行做列值解析,整体逻辑完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 04:45:01