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

如何用单语句将List<Definition>转为Map<String, Map<String, Definition>>?

问题:将List转换为嵌套Map的单语句实现

需求:已将对象数组转为List<Definition>,需要转换为Map<String, Map<String, Definition>>,外层Map的键为defName,内层Map的键为defDesc,且同一defName下的defDesc唯一。

原始对象数组:

[
    {
        "defName": "Project",
        "defDesc": "Project 1",
        "defID": "abcd123",
        "defClass": "class1"
    },
    {
        "defName": "Project",
        "defDesc": "Project 2",
        "defID": "asdoihw1345",
        "defClass": "class2"
    },
    {
        "defName": "Project",
        "defDesc": "Project 3",
        "defID": "ewrwu123",
        "defClass": "class3"
    },
    {
        "defName": "Product",
        "defDesc": "Product 1",
        "defID": "pgkorejgoi1234",
        "defClass": "class1"
    },
    {
        "defName": "Product",
        "defDesc": "Product 2",
        "defID": "asadsad2343",
        "defClass": "class2"
    },
    {
        "defName": "Product",
        "defDesc": "Product 3",
        "defID": "4dgaksld",
        "defClass": "class3"
    }
]

原有两步实现:

List<Definition> definitions = // 从JSON获取的列表
Map<String, List<Definition>> definitionByName = definitions.stream().collect(Collectors.groupingBy(Definition::getDefName));
Map<String, Map<String, Definition>> definitionMap = new HashMap<>();
definitionByName.forEach((name, definitionList) -> {
    Map<String, Definition> definitionDescMap = definitionList.stream()
            .collect(Collectors.toMap(def -> def.getDefDesc(), Function.identity()));
    definitionMap.put(name, definitionDescMap);
});

Java 8 单语句解决方案

可以直接使用Collectors.groupingBy的重载方法,指定下游收集器为Collectors.toMap,一步完成嵌套Map的转换:

List<Definition> definitions = // 从JSON获取的列表
Map<String, Map<String, Definition>> definitionMap = definitions.stream()
        .collect(Collectors.groupingBy(
                Definition::getDefName,
                Collectors.toMap(Definition::getDefDesc, Function.identity())
        ));

说明

  • 第一个参数Definition::getDefName是外层Map的分组键提取函数;
  • 第二个参数是下游收集器,将每个分组内的List<Definition>直接转换为以defDesc为键、Definition对象为值的内层Map;
  • 由于你明确同一defName下的defDesc唯一,无需处理键冲突,所以不用额外指定冲突合并函数。

Java 8+ 优化参考

如果后续使用Java 16及以上版本,写法逻辑和Java 8一致,但可以根据场景补充冲突处理逻辑(比如出现defDesc重复时):

Map<String, Map<String, Definition>> definitionMap = definitions.stream()
        .collect(Collectors.groupingBy(
                Definition::getDefName,
                Collectors.toMap(
                        Definition::getDefDesc,
                        Function.identity(),
                        (existing, replacement) -> replacement // 冲突时保留新对象
                )
        ));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 10:37:28