【问题标题】:java stream List<Map<String,Double>> need average based on the stringjava stream List<Map<String,Double>> 需要根据字符串取平均值
【发布时间】:2019-08-10 05:48:36
【问题描述】:

我需要列表的平均值

    List<Measurement> measurements = new ArrayList<>();

    Measurement m1 = new Measurement();
    Map<String,Double> map1 = new HashMap<>();
    map1.put("age",18.0);
    map1.put("score",88.0);
    map1.put("rating",5.0);
    m1.setMetric(map1);

    Measurement m2 = new Measurement();
    Map<String,Double> map2 = new HashMap<>();
    map2.put("age",21.0);
    map2.put("score",null);
    map2.put("rating",23.0);
    m2.setMetric(map2);

    Measurement m3 = new Measurement();
    Map<String,Double> map3 = new HashMap<>();
    map3.put("age",31.0);
    map3.put("score",32.0);
    map3.put("rating",null );
    m3.setMetric(map3);

    measurements.add(m1);
    measurements.add(m2);
    measurements.add(m3);

如何获得上述地图列表的平均年龄。也可以通过忽略空值来获得平均分。

任何帮助将不胜感激。自 3 天以来,我一直在努力修复。 先感谢您。

【问题讨论】:

  • 你能分享Measurement对象吗?

标签: java list dictionary filter java-stream


【解决方案1】:

对于这样的Measurement 类:

class Measurement {

    Map<String, Double> map;

    public void setMetric(Map<String, Double> map) {
        this.map = map;
    }
}

如何查找平均“年龄”(使用流):

Double averageAge = measurements.stream()
        .collect(Collectors.averagingDouble(node -> node.map.getOrDefault("age", 0D)));

对于可为空的“分数”进行流式处理:

如何通过 null 检查找到平均“年龄”(使用流):

Double averageAge = measurements.stream()
        .filter(node -> node.map.get("score") != null)
        .collect(Collectors.averagingDouble(node -> node.map.getOrDefault("score", 0D)));

在上面的代码中你有node.map 其中map 是字段表单类。可以替换为getMap()或不同的方法返回值(由setMetric()设置)

如何查找平均“年龄”(使用循环):

Double average = 0D;
for (Measurement measure : measurements) {
    average += measure.map.getOrDefault("age", 0D);
}
average /= measurements.size();

如何通过 null 检查找到平均“分数”(使用循环):

Double average = 0D;
int counter = 0;
for (Measurement measure : measurements) {
    if (measure.map.get("score") != null) {
        average += measure.map.getOrDefault("score", 0D);
        counter++;
    }
}
average /= counter;

如何通过空值检查找到最小的“分数”(使用循环):

Double min = Double.MAX_VALUE;

for (Measurement measure : measurements) {
    Double score = measure.map.get("score");
    if (score != null && score < min) {
        min = score;
    }
}

System.out.println(min);

如何找到最大的“年龄”(使用流)

Double max = measurements.stream()
        .filter(node -> node.map.get("score") != null)
        .mapToDouble(node -> node.map.get("score"))
        .max()
        .orElse(0.0);

【讨论】:

  • 非常感谢您的快速回复。 :) 非常感谢。我还需要具有空值的“分数”的平均值。我得到空指针。请在这方面帮助我
  • 我需要的是 - 如果有空;忽略它;而不是添加平均值。例如:值 1:10,值 2:null,值 3:30 - 然后平均值为 (value1+value3)/2。不是 (value1+value3)/3
  • 这个更适合我;但是如果想要最大值或最小值而不是平均值?请告诉我
  • @Hruday 添加了最小值和最大值。
【解决方案2】:

您可以使用以下方法计算每个地图键的平均值:

Map<String, Double> result = Stream.of(m1, m2, m3)
        .flatMap(m -> m.getMap1().entrySet().stream()
                       .filter(e -> e.getValue() != null))
        .collect(Collectors.groupingBy(e -> e.getKey(), 
                Collectors.averagingDouble(e -> e.getValue())));

您的测试数据的输出是{score=60.0, rating=14.0, age=23.333333333333332}

【讨论】:

  • 谢谢;如果我想要最大值而不是平均值怎么办?请告诉我
  • @Hruday 您可以使用Collectors.maxBy 代替averagingDouble。但是会进行一些清理以消除值中的Optional
  • 恕我直言,将.filter(e -&gt; e.getValue() != null) 从传递给flatMap 的函数移动到另一个流的后续步骤时,代码变得更具可读性。
【解决方案3】:

你可以得到平均年龄:

Double averageAge = measurements.stream()
        .flatMap(a -> a.getMetric().entrySet().stream())
        .filter(a -> a.getKey().equals("age"))
        .mapToDouble(Map.Entry::getValue)
        .average()
        .orElse(Double.NaN);

同样,平均分数需要额外的过滤条件来排除 null 值。

【讨论】:

  • 我猜你不必使用filter。它可能看起来像.mapToDouble(map -&gt; map.get("age"))
  • @Ruslan 在另一个计算中考虑到null 分数值的情况,使其一般化。
  • 如果你想避免空值,只需添加一个.filter(Objects::nonNull)
  • 您可以使用.map(a -&gt; a.getMetric()) .flatMapToDouble(m -&gt; m.containsKey("age")? DoubleStream.of(m.get("age")): DoubleStream.empty())。此外,没有理由将结果放入 Double 而不是仅使用 double
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-06
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
相关资源
最近更新 更多