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

Java中如何从HashMap动态取值 字段对比状态自动填充问题咨询

问题根因
  • 循环逻辑错误:嵌套双重循环冗余,且每次对比单个字段就调用initMap全量覆盖HashMap所有字段的状态,最终仅保留最后一个字段的校验结果,其他字段状态被错误覆盖
  • 全局状态判定逻辑错误:原有逻辑只要有一个字段匹配成功就设全局状态为PASS,不符合多字段校验的预期
  • 流操作未自动释放资源,存在资源泄漏风险
修复方案

1. 预定义字段顺序常量

首先在类中定义静态常量,和待对比字段的顺序严格对应,保证inputs、outputs列表的元素顺序和字段名顺序一致:

import java.util.Arrays;
import java.util.List;

// 待对比字段顺序,和inputs、outputs列表的元素顺序一一对应
private static final List<String> COMPARE_FIELDS = Arrays.asList(
    "Book Ref",
    "Trade Date",
    "Start Date",
    "End Date",
    "Period Multiplier",
    "Notional",
    "Currency",
    "Rate",
    "Frequency Multiplier",
    "Day count"
);
// 状态常量,避免拼写错误
private static final String STATUS_OK = "Ok";
private static final String STATUS_NOT_OK = "not Ok";

2. 重写compareValues对比方法

删除冗余的双重循环,单次遍历逐个更新字段状态,统一判定全局校验结果:

public static void compareValues(List<String> inputs, List<String> outputs, XrayFields fields, TradeData data, MKTWireIRS mkt) throws ParseException, InterruptedException {
    // 前置校验:输入输出列表长度必须和预设字段数一致
    if (inputs.size() != COMPARE_FIELDS.size() || outputs.size() != COMPARE_FIELDS.size()) {
        fields.setStatus("FAIL");
        fields.setComment("待对比字段数量不匹配");
        throw new IllegalArgumentException("inputs/outputs长度与预设字段数不符");
    }

    Map<String, String> statusMap = new HashMap<>();
    boolean isAllPass = true;
    StringBuilder commentBuilder = new StringBuilder();

    try {
        // 按索引遍历,逐个更新对应字段的校验状态
        for (int i = 0; i < COMPARE_FIELDS.size(); i++) {
            String field = COMPARE_FIELDS.get(i);
            String inputVal = inputs.get(i);
            String outputVal = outputs.get(i);
            
            if (inputVal.equals(outputVal)) {
                System.out.printf("ok: %s = %s%n", inputVal, outputVal);
                statusMap.put(field, STATUS_OK);
            } else {
                System.out.printf("not ok: %s != %s%n", inputVal, outputVal);
                statusMap.put(field, STATUS_NOT_OK);
                isAllPass = false;
                commentBuilder.append(String.format("字段[%s]不匹配:预期值%s,实际值%s;", field, inputVal, outputVal));
            }
        }

        // 统一设置全局校验状态
        if (isAllPass) {
            fields.setComment("所有字段校验通过");
            fields.setStatus("PASS");
        } else {
            fields.setStatus("FAIL");
            fields.setComment(commentBuilder.toString());
        }

        // 生成CSV对比凭证
        WriterCSV csvWriter = new WriterCSV();
        csvWriter.reportMKTWireToOutputIRS(data, mkt, statusMap);
    } catch (Exception e) {
        System.out.println("对比流程异常:" + e.getMessage());
        e.printStackTrace();
    }
}

3. 优化CSV写入方法的流操作

使用try-with-resources自动关闭流,无需手动flush、close,避免资源泄漏:

public void reportMKTWireToOutputIRS(TradeData data2, MKTWireIRS mkt, Map<String, String> map ) throws ParseException, InterruptedException {
    // 用try-with-resources自动管理流资源
    try (FileWriter fw = new FileWriter(new File(CSV_MKTWire + Setup.IRScsv));
         CSVWriter cw = new CSVWriter(fw)) {
        
        // 原有数据格式化逻辑保持不变
        String month = PropertyNames.deCapitalize(data2.getPeriod());
        String monthReset = PropertyNames.deCapitalize(data2.getResetFrequencyPeriod());
        String formatTradeDateMKT = Utils.formatDateToCompareMKTWire(data2.getTradeDateIRS());
        String formatStartDateMKT = Utils.formatDateToCompareMKTWire(data2.getStart_Date());
        String formatMAturityDateMKT = Utils.formatDateToCompareMKTWire(data2.getMaturity_Date());
        String rateActual = Utils.roundDecimal(data2.getRateIRS());
        String rateFormat = Utils.roundRateMKTwire(mkt.getRateIRS());
        String notionalFormat = data2.getNotional().charAt(0) + "M";

        String[] headers = { "Output Field", "Output Value", " MKTWire Field", " MKTWire Value", "Status" };
        List<String[]> data = new ArrayList<String[]>();

        String[] book = { "Book Ref", data2.getBookRef() + data2.getBookType(),"Book MKTWire",mkt.getBookIRS(), map.get("Book Ref")};
        String[] tradeDate = { "Trade Date", formatTradeDateMKT,"Trade Date MKTWire",mkt.getTradeDateIRS(), map.get("Trade Date")};
        String[] startDate = { "Start Date", formatStartDateMKT, "Start Date MKTWire",mkt.getStartDate(), map.get("Start Date") };
        String[] maturity = { "End Date", formatMAturityDateMKT, "End Date MKTWire",mkt.getEndDate(), map.get("End Date") };
        String[] tenor = { "Period Multiplier", data2.getPeriodMultiplier() + month, "Tenor MKTWire",mkt.getTenorIRS(), map.get("Period Multiplier") };
        String[] notional = { "Notional", notionalFormat, "Notional MKTWire", mkt.getNotionalValueIRS(), map.get("Notional") };
        String[] currency = { "Currency", data2.getCurrencyIRS(), "Currency MKTWire", mkt.getCurrencyIRS(), map.get("Currency") };
        String[] rate = { "Rate", rateActual, "Rate MKTWire", rateFormat, map.get("Rate") };
        String[] resetFrequency = { "Frequency Multiplier", data2.getResetFrequencyMultiplier() + monthReset, "Frequency Multiplier MKTWire", mkt.getResetFrequencyIRS(),map.get("Frequency Multiplier") };
        String[] dayCount = { "Day Count", data2.getDayCount(), "Day Count MKTWire", mkt.getDayCountIRS(), map.get("Day count") };

        data.add(headers);
        data.add(book);
        data.add(tradeDate);
        data.add(startDate);
        data.add(maturity);
        data.add(tenor);
        data.add(notional);
        data.add(currency);
        data.add(rate);
        data.add(resetFrequency);
        data.add(dayCount);
        
        cw.writeAll(data);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 15:45:05