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(); } } }
代码逻辑说明
- 表头合并:确保公共列只出现一次,同时保留两个文件的所有非公共列。
- 数据行合并:
- 匹配到公共列值时,直接追加非公共列数据;
- 未匹配到公共列值时,用空字符串填充第一个文件的列,保证输出格式统一。
- 资源管理:用try-catch捕获IO异常,最后关闭所有流资源,避免内存泄漏。
小提示
如果你的CSV文件使用了非逗号的分隔符,可以在初始化CSVReader和CSVWriter时指定,比如new CSVReader(reader, ';')。
内容的提问来源于stack exchange,提问作者Bony
相关产品推荐
相关产品推荐

