Java如何将Map<String, Map<String, String>>转为指定格式字符串
嵌套Map统计结果转目标字符串实现
你当前的两层分组统计逻辑已经得到了正确的中间结果,只需要遍历两层Map的条目做字符串拼接即可,也可以简化整个流程,跳过中间嵌套Map的生成直接得到结果。
方案1:基于你现有代码的结果做转换
针对已经生成的Map<String, Map<String, String>>类型统计结果,直接通过Stream扁平化遍历两层Entry,再拼接即可:
String output = collect.entrySet().stream() .flatMap(deptEntry -> deptEntry.getValue().entrySet().stream() .map(curEntry -> deptEntry.getKey() + " " + curEntry.getValue()) ) .collect(Collectors.joining(", "));
注意:你给出的预期输出中
Moscow 200 usd的币种为小写,其余为大写,属于笔误。如果需要统一币种大小写,可以在拼接时对币种字段调用toUpperCase()/toLowerCase()处理即可。
方案2:优化实现,跳过中间嵌套Map
不需要生成两层嵌套Map,直接用「部门+币种」作为联合key分组统计金额,一步拼接出最终结果,代码更简洁:
// 先修正你原代码的笔误:A::getAmount 替换为 Report::getAmount String output = list.stream() .collect(Collectors.groupingBy( // 联合key:[部门名, 币种] report -> Arrays.asList(report.getDepartmentName(), report.getCurrency()), // 按分组统计金额总和,空值安全处理 Collectors.reducing( BigDecimal.ZERO, Report::getAmount, (sum, amount) -> amount == null ? sum : sum.add(amount) ) )) .entrySet().stream() // 拼接单条记录格式:部门 金额 币种 .map(entry -> String.format("%s %s %s", entry.getKey().get(0), entry.getValue(), entry.getKey().get(1) )) // 所有记录用逗号分隔 .collect(Collectors.joining(", "));
原代码注意点
- 原分组逻辑中
map(A::getAmount)为笔误,需要替换为map(Report::getAmount)才能正常编译运行 - 原逻辑中
findFirst().get()存在极小概率抛异常的风险,更稳妥的写法是替换为findFirst().orElse(""),因为分组后的子列表不可能为空,实际运行不会触发问题。
内容的提问来源于stack exchange,提问作者AbrA
相关产品推荐
相关产品推荐

