创建地图从地图。

4

我有一个名为AB的类:

class AB{
  private final String a;
  private final String b;

  public AB(String a, String b) {
    this.a = a;
    this.b = b;
  }

  public String getB() {
    return b;
  }

  public String getA() {
    return a;
  }

  @Override
  public boolean equals(Object o) {...}

  @Override
  public int hashCode() {...}
}

现在,我创建一个名为Map<AB,Float> mapWithData的映射表来计算服务器响应中a服务名称和b服务端口在stats.log中出现的次数。
我们将它们全部加起来存入servicesNamePort.merge(new AB(...,...), 1.0f, Float::sum)这个映射表中。
如何从Map<AB,Float> mapWithData创建一个映射表,其中键是b,值是以a为键,float为值的映射表,即Map<String **(b)**, Map<String**(a)**,Float>>呢?
我尝试使用Collectors.groupingBy,但收到了这个回答:
Map<String, List<Map.Entry<AB, Float>>> collect = mapWithData.entrySet()
            .stream()
            .collect(Collectors.groupingBy(abEntry-> abEntry.getKey().getB()));

感谢您的任何帮助。
1个回答

3

你错过的一点是,你可以将另一个Collector作为第二个参数传递给groupingBy收集器,以指定如何收集组:

Map<String, Map<String, Double>> collect = mapWithData.entrySet()
    .stream()
    .collect(Collectors.groupingBy(e -> e.getKey().getB(),
                 Collectors.groupingBy(e -> e.getKey().getA(),
                     Collectors.summingDouble(e -> e.getValue()))));

这是与您问题最相关的答案,因为没有直接支持 Float 的方法。

但是由于这个数字应该是一个“计数”,我更愿意使用 Integer 或者 Long

如果您的 mapWithData 声明为 Map<AB,Long>,您可以使用

Map<String, Map<String, Long>> collect = mapWithData.entrySet()
    .stream()
    .collect(Collectors.groupingBy(e -> e.getKey().getB(),
                 Collectors.groupingBy(e -> e.getKey().getA(),
                     Collectors.summingLong(e -> e.getValue()))));

如果确实需要一个Float结果,您可以使用以下方法:
Map<String, Map<String, Float>> collect = mapWithData.entrySet()
    .stream()
    .collect(Collectors.groupingBy(e -> e.getKey().getB(),
                 Collectors.groupingBy(e -> e.getKey().getA(),
                     Collectors.collectingAndThen(
                         Collectors.summingDouble(e->e.getValue()), Double::floatValue))));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接