将地图数据组列表到Java中的嵌套HashMap

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将地图数据组列表到Java中的嵌套HashMap相关的知识,希望对你有一定的参考价值。

输入:我有一个Map(键 - 值对)列表和分组键

egList<Map<String,String>> inputData json

[
 {
    'a': 'German',
    'b': 'Audi',
    'e': 'T3'
 },
 {
    'a': 'German',
    'b': 'BMW',
    'c': 'T6'
 },
 {
    'a': 'American',
    'b': 'Tesla',
    'c': 'T6'
 }
]

和groupingKeys = a and b

对于分组键a - >我将创建两个桶,一个用于德语和其他美国,在每个桶中我将再次为b的值创建桶,检查以下

我想生成以下内容:Map<String, Map<String, List<Map>> - 地图的嵌套==分组键的数量,这里是2

{
   German: {
       Audi: [
            {
               'a': 'German',
               'b': 'Audi',
               'e': 'T3'
            }
       ],
       BMW: [
            {
               'a': 'German',
               'b': 'BMW',
               'c': 'T6'
            }
       ]
   },
   American: {
      Tesla: [
          {
            'a': 'American',
            'b': 'Tesla',
            'c': 'T6'
          }
      ]
   }
}

我试过的事情:

inputData.stream().collect(Collectors.groupingBy(mapItem -> this.constructGroupingKey(groupingKeys, mapItem)));

//constructGroupingKey - this joins the values of of given grouping keys

通过这种方式,我可以构建连接键,例如德国 - 奥迪或德国 - 宝马并保存匹配项目,但这不是我想要的。

正如@Naman在这里所说的关于具体的类 - 跟随它使它成为一个班轮但我无法对数据做出假设,它的类型为Map

Map<String, Map<String, List<ConcreteClass>>> output = inputData.stream().collect(Collectors.groupingBy(ConcreteClass::getCountry, Collectors.groupingBy(ConcreteClass::getCarType)));

非常感谢其他想法,谢谢。我也很好奇,如果我可以根据给定的数据派生分组而不指定分组键。

输入具有动态性质,键和值由输入定义

答案

只需双击输入的表示形式作为具体类。它会看起来更简单和干净:

Map<String, Map<String, List<ThrowAway>>> multipleGrouping(List<ThrowAway> inputData) {
    return inputData.stream()
            .collect(Collectors.groupingBy(ThrowAway::getA,
                    Collectors.groupingBy(ThrowAway::getB)));
}

我刚刚创建了一个与地图表示相同的示例类:

class ThrowAway {
    String a;
    String b;
    String c;

    String getA() {
        return a;
    }

    String getB() {
        return b;
    }
}
另一答案

由于您正在寻找动态解决方案,这是另一种方法:

您可以使用以下分组方法传递两个键:

public Map<String, Map<String, List<Map<String, String>>>> group(List<Map<String, String>> list, String key1, String key2) {
    return list.stream().collect(
            Collectors.groupingBy(m -> m.get(key1),
                    Collectors.groupingBy(m -> m.get(key2))
            )
    );
}

这里的问题是,如果地图中不存在您获得NullPointerException的密钥。要防止这种情况,您可以使用带有默认密钥的map.getOrDefault()

public Map<String, Map<String, List<Map<String, String>>>> group(List<Map<String, String>> list, String key1, String key2, String noneKey) {
    return list.stream().collect(
            Collectors.groupingBy(m -> m.getOrDefault(key1, noneKey),
                    Collectors.groupingBy(m -> m.getOrDefault(key2, noneKey))
            )
    );
}

使用以下选项调用其中一个方法:

Map<String, Map<String, List<Map<String, String>>>> result = group(list, "a", "b");

要么

Map<String, Map<String, List<Map<String, String>>>> result = group(list, "a", "b", "none");

以上是关于将地图数据组列表到Java中的嵌套HashMap的主要内容,如果未能解决你的问题,请参考以下文章

反序列化时需要一个列表,但得到一个带有嵌套对象的类 java.util.HashMap

Java的HashMap

将两个列表组合成地图(Java)的最佳方法是啥?

使用Java 8模式匹配将地图转换为列表

Pandas 数据框以列中的唯一值作为键,嵌套列表作为值

Python:在元组列表和嵌套列表中比较并查找匹配项