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

Java实现两个CSV文件按id比对并输出指定列数值差异的方案问询

优化实现方案

核心思路是用id+subId作为联合唯一主键映射对应行的数值,直接消除多层嵌套集合的复杂逻辑,查找效率为O(1),实现非常简洁。

前置设计

因为匹配规则是id和subId联合唯一,所以直接用二者作为Map的键,对应值存储c、d两列的数值即可:

  • 优先用Java 16+的record定义不可变对象,自动生成equals/hashCode,无需手动重写
  • 数值类型用BigDecimal避免浮点运算精度丢失
// 联合主键:id + subId
record RecordKey(String id, String subId) {}
// 对应行的c、d列数值
record ColumnPair(BigDecimal c, BigDecimal d) {}

如果是Java 16以下版本,手动写普通类重写equals和hashCode方法即可。

完整实现代码

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class CsvComparator {
    public static void main(String[] args) throws IOException {
        // 读取两个CSV文件存入Map
        Map<RecordKey, ColumnPair> csv1Map = readCsv("csv1.csv");
        Map<RecordKey, ColumnPair> csv2Map = readCsv("csv2.csv");

        // 遍历匹配计算差值
        for (Map.Entry<RecordKey, ColumnPair> entry : csv1Map.entrySet()) {
            RecordKey key = entry.getKey();
            ColumnPair csv1Val = entry.getValue();
            ColumnPair csv2Val = csv2Map.get(key);
            
            // 跳过仅在单个CSV存在的key,可按需增加提示
            if (csv2Val == null) continue;

            // 计算差值(取绝对值,保留两位小数)
            BigDecimal diffC = csv2Val.c().subtract(csv1Val.c()).abs().setScale(2);
            BigDecimal diffD = csv2Val.d().subtract(csv1Val.d()).abs().setScale(2);

            // 按要求格式输出
            System.out.printf("difference of column c of id %s and sub id %s is : %.2f%n", 
                    key.id(), key.subId(), diffC);
            System.out.printf("difference of column d of id %s and sub id %s is : %.2f%n%n", 
                    key.id(), key.subId(), diffD);
        }
    }

    // 读取CSV文件转为Map结构
    private static Map<RecordKey, ColumnPair> readCsv(String filePath) throws IOException {
        Map<RecordKey, ColumnPair> map = new HashMap<>();
        Files.lines(Paths.get(filePath))
                .filter(line -> !line.isBlank()) // 跳过空行
                .forEach(line -> {
                    String[] parts = line.split(",");
                    RecordKey key = new RecordKey(parts[0], parts[1]);
                    BigDecimal c = new BigDecimal(parts[2]);
                    BigDecimal d = new BigDecimal(parts[3]);
                    map.put(key, new ColumnPair(c, d));
                });
        return map;
    }
}

方案优势

  • 结构简单:仅需单层级Map结构,无多层嵌套,逻辑可读性极强
  • 效率更高:HashMap的匹配查找为O(1),远高于遍历List匹配的O(n)效率
  • 精度可控:用BigDecimal存储运算,完全避免浮点精度丢失问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 01:15:04