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

Java实现基于多列匹配筛选CSV文件并生成新文件

Java实现CSV文件匹配筛选

输入文件示例

文件1(file1.csv):

ID,NAME
1,FOO
2,BAR
3,XYZ

文件2(file2.csv):

ID,NAME,DOB
3,XYZ,02/03/1999
4,BAR,01/01/1995
1,FOO,01/01/1996

预期输出

ID,NAME,DOB
3,XYZ,02/03/1999
1,FOO,01/01/1996

核心实现思路

  • 先读取文件1,将所有(ID, NAME)组合存入HashSet,利用集合的O(1)查找特性提升匹配效率
  • 遍历文件2的每一行,检查当前行的ID和NAME是否存在于上述集合中
  • 将符合条件的行(包含表头)写入结果文件

使用OpenCSV库实现

原生Java处理CSV需要手动处理分隔符、转义字符等场景,容易出错,推荐使用成熟的第三方库OpenCSV简化操作。

引入依赖(Maven)

<dependency>
    <groupId>com.opencsv</groupId>
    <artifactId>opencsv</artifactId>
    <version>5.6</version>
</dependency>

完整代码示例(适用于中小文件)

该版本一次性读取文件内容到内存,适合文件体积不大的场景:

import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import com.opencsv.exceptions.CsvException;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class CsvMatcher {
    public static void main(String[] args) {
        String file1Path = "path/to/file1.csv";
        String file2Path = "path/to/file2.csv";
        String outputPath = "path/to/result.csv";

        Set<String> matchPairs = new HashSet<>();

        // 读取文件1,构建匹配集合
        try (CSVReader reader1 = new CSVReader(new FileReader(file1Path))) {
            List<String[]> allRows = reader1.readAll();
            // 跳过表头,从第二行开始处理数据
            for (int i = 1; i < allRows.size(); i++) {
                String[] row = allRows.get(i);
                if (row.length >= 2) {
                    // 拼接ID和NAME作为匹配键,trim避免空格干扰
                    String key = row[0].trim() + "," + row[1].trim();
                    matchPairs.add(key);
                }
            }
        } catch (IOException | CsvException e) {
            e.printStackTrace();
            return;
        }

        // 读取文件2并筛选符合条件的行
        try (CSVReader reader2 = new CSVReader(new FileReader(file2Path));
             CSVWriter writer = new CSVWriter(new FileWriter(outputPath))) {

            List<String[]> file2Rows = reader2.readAll();
            // 先写入表头
            writer.writeNext(file2Rows.get(0));

            // 遍历数据行,筛选匹配项
            for (int i = 1; i < file2Rows.size(); i++) {
                String[] row = file2Rows.get(i);
                if (row.length >= 3) {
                    String key = row[0].trim() + "," + row[1].trim();
                    if (matchPairs.contains(key)) {
                        writer.writeNext(row);
                    }
                }
            }
            System.out.println("筛选完成,结果已写入:" + outputPath);
        } catch (IOException | CsvException e) {
            e.printStackTrace();
        }
    }
}

大文件优化版本(逐行读取)

如果CSV文件体积较大,一次性读入内存会导致内存溢出,可改用逐行读取的方式:

import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import com.opencsv.exceptions.CsvException;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

public class LargeCsvMatcher {
    public static void main(String[] args) {
        String file1Path = "path/to/file1.csv";
        String file2Path = "path/to/file2.csv";
        String outputPath = "path/to/result.csv";

        Set<String> matchPairs = new HashSet<>();

        // 逐行读取文件1
        try (CSVReader reader1 = new CSVReader(new FileReader(file1Path))) {
            String[] nextLine;
            // 跳过表头
            reader1.readNext();
            while ((nextLine = reader1.readNext()) != null) {
                if (nextLine.length >= 2) {
                    String key = nextLine[0].trim() + "," + nextLine[1].trim();
                    matchPairs.add(key);
                }
            }
        } catch (IOException | CsvException e) {
            e.printStackTrace();
            return;
        }

        // 逐行读取文件2并筛选
        try (CSVReader reader2 = new CSVReader(new FileReader(file2Path));
             CSVWriter writer = new CSVWriter(new FileWriter(outputPath))) {

            // 写入表头
            String[] header = reader2.readNext();
            if (header != null) {
                writer.writeNext(header);
            }

            String[] nextLine;
            while ((nextLine = reader2.readNext()) != null) {
                if (nextLine.length >= 3) {
                    String key = nextLine[0].trim() + "," + nextLine[1].trim();
                    if (matchPairs.contains(key)) {
                        writer.writeNext(nextLine);
                    }
                }
            }
            System.out.println("筛选完成,结果已写入:" + outputPath);
        } catch (IOException | CsvException e) {
            e.printStackTrace();
        }
    }
}

注意事项

  • 替换代码中的文件路径为实际的本地文件路径
  • 使用trim()是为了避免字段前后的空格导致匹配失败,如果确认CSV文件中没有多余空格,可以去掉该方法
  • 如果需要处理带引号的CSV字段,OpenCSV会自动处理,无需额外编码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 06:36:34