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
相关产品推荐
相关产品推荐

