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

Java中基于公共列合并CSV文件:代码实现续写求助

基于公共列合并两个CSV文件的Java实现方案

我来帮你补全代码并修正几个关键细节,这样就能实现你想要的CSV合并效果啦:

关键问题修正

首先得注意:Java数组是0索引的,你示例里的sno是CSV的第一列,所以commonCol应该设为0,而不是1,不然会拿错匹配的列值,这是原代码里的一个小疏漏。

完整实现代码

下面是补全后的完整代码,关键部分我加了注释说明:

import au.com.bytecode.opencsv.CSVReader;
import au.com.bytecode.opencsv.CSVWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CSVMerger {
    public static void main(String[] args) {
        try {
            // 初始化两个CSV读取器
            CSVReader r1 = new CSVReader(new FileReader("c:/csv/file1.csv"));
            CSVReader r2 = new CSVReader(new FileReader("c:/csv/file2.csv"));
            // 用HashMap存储file1的数据,key为公共列sno的值
            Map<String, String[]> file1Data = new HashMap<>();
            int commonColIndex = 0; // sno是第一列,数组索引为0

            // 读取file1的表头并跳过(后续会合并表头)
            String[] header1 = r1.readNext();
            // 读取file1的所有数据行,存入HashMap
            String[] line1;
            while ((line1 = r1.readNext()) != null) {
                file1Data.put(line1[commonColIndex], line1);
            }

            // 读取file2的表头
            String[] header2 = r2.readNext();
            // 合并表头:保留file1的所有列,再添加file2中除公共列外的其他列
            List<String> mergedHeader = new ArrayList<>();
            for (String col : header1) {
                mergedHeader.add(col);
            }
            for (String col : header2) {
                if (!col.equals(header1[commonColIndex])) { // 跳过重复的公共列
                    mergedHeader.add(col);
                }
            }

            // 处理file2的数据行,合并到file1的数据集里
            String[] line2;
            while ((line2 = r2.readNext()) != null) {
                String commonValue = line2[commonColIndex];
                if (file1Data.containsKey(commonValue)) {
                    // 找到匹配的sno,将file2的非公共列追加到file1对应行的末尾
                    String[] existingLine = file1Data.get(commonValue);
                    List<String> mergedLine = new ArrayList<>();
                    for (String val : existingLine) {
                        mergedLine.add(val);
                    }
                    for (int i = 0; i < line2.length; i++) {
                        if (i != commonColIndex) { // 跳过公共列,避免重复
                            mergedLine.add(line2[i]);
                        }
                    }
                    file1Data.put(commonValue, mergedLine.toArray(new String[0]));
                } else {
                    // 没有匹配的sno,补全file1的列(用空字符串填充),再添加file2的行数据
                    List<String> newLine = new ArrayList<>();
                    // 先填充file1的列,公共列用file2的sno值,其他列用空字符串
                    for (int i = 0; i < header1.length; i++) {
                        if (i == commonColIndex) {
                            newLine.add(commonValue);
                        } else {
                            newLine.add("");
                        }
                    }
                    // 再添加file2的非公共列
                    for (int i = 0; i < line2.length; i++) {
                        if (i != commonColIndex) {
                            newLine.add(line2[i]);
                        }
                    }
                    file1Data.put(commonValue, newLine.toArray(new String[0]));
                }
            }

            // 将合并后的数据写入新的CSV文件
            CSVWriter writer = new CSVWriter(new FileWriter("c:/csv/merged.csv"));
            // 先写入合并后的表头
            writer.writeNext(mergedHeader.toArray(new String[0]));
            // 写入所有合并完成的数据行
            for (String[] line : file1Data.values()) {
                writer.writeNext(line);
            }

            // 关闭所有IO资源,避免资源泄漏
            r1.close();
            r2.close();
            writer.close();
            System.out.println("CSV文件合并完成!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

代码逻辑说明

  1. 表头合并:确保公共列只出现一次,同时保留两个文件的所有非公共列。
  2. 数据行合并:
    • 匹配到公共列值时,直接追加非公共列数据;
    • 未匹配到公共列值时,用空字符串填充第一个文件的列,保证输出格式统一。
  3. 资源管理:用try-catch捕获IO异常,最后关闭所有流资源,避免内存泄漏。

小提示

如果你的CSV文件使用了非逗号的分隔符,可以在初始化CSVReader和CSVWriter时指定,比如new CSVReader(reader, ';')。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 18:52:42