java8 按键减少的地图列表

sle*_*lee 3 java java-8

我有一个地图列表如下。

我想按键对条目集进行分组,如果键不存在,则填写 0。

    List<Map<String, Double>> props = Lists.newArrayList();
    Map<String, Double> m1 =  Maps.newHashMap();
    m1.put("a", 0.1);
    m1.put("b", 0.5);
    m1.put("c", 0.6);

    Map<String, Double> m2 =  Maps.newHashMap();
    m2.put("a", 0.3);
    m2.put("d", 0.1);

    Map<String, Double> m3 = Maps.newHashMap();
    m3.put("a", 0.2);

    props.add(m1); props.add(m2); props.add(m3);
Run Code Online (Sandbox Code Playgroud)

预期结果:

{a=[0.1, 0.3, 0.2], b=[0.5, 0, 0], c=[0.6,0,0], d=[0,0.1,0]}
Run Code Online (Sandbox Code Playgroud)

我有个主意:

  1. 找到所有不同的键
  2. 用值 0 填充每个缺失键的映射
  3. groupby 键,值映射到列表

有什么好主意吗?

Sha*_*mud 5

它可以在单行 lamda 和流中完成,除非情况下用值 0 填充每个缺失键的映射

  Map<String, List<Double>> collect = Stream.of(m1, m2, m3)
                   .flatMap(map -> map.entrySet().stream())
                   .collect(groupingBy(
                            Map.Entry::getKey,
                            mapping(Map.Entry::getValue, toList()))
                    );

  System.out.println(collect);
Run Code Online (Sandbox Code Playgroud)

这将产生输出为

{a=[0.1, 0.3, 0.2], b=[0.5], c=[0.6], d=[0.1]}
Run Code Online (Sandbox Code Playgroud)

这里静态工厂方法Collectors.groupingBy()用于通过 Key ( classifier) 和映射方法 ( collector)对所有映射的连接条目进行分组。

如果这是明显的情况,您必须用值 0 填充每个缺失键的映射,那么有几种方法可以做到这一点。@abhi 在其他答案中提到的那个。随着他的想法,我想这样做

  Set<String> allKeys = Sets.newHashSet();
  props.forEach(prop -> allKeys.addAll(prop.keySet()));
  allKeys.forEach(k -> props.forEach(m -> m.putIfAbsent(k, 0.0)));
Run Code Online (Sandbox Code Playgroud)

逸岸这会修改你的原始的地图,allKeys0作为价值ifNotPresent。如果此修改导致您出现问题,您可以更喜欢复制您的地图以拥有单独的集合。

这将确保您想要的输出

{a=[0.1, 0.3, 0.2], b=[0.5, 0.0, 0.0], c=[0.6, 0.0, 0.0], d=[0.0, 0.1, 0.0]}
Run Code Online (Sandbox Code Playgroud)

注意:您会发现这篇关于使用 Java 8 流进行分组的文章很有趣