【问题标题】:How can I get some statistics using java 8 stream with object list如何使用带有对象列表的 java 8 流获取一些统计信息
【发布时间】:2021-06-09 11:56:27
【问题描述】:

我有一个List<SqlResult>。我需要从 SqlResult 的聚合中得到一个List<Result>。例如,

SqlResult(输入)

public class SqlResult{
  private String key1;
  private String key2;
  private Double val;
  // getters, setters and constructor

结果数据类

public class Result{
  private String key1;
  private String key2;
  private Double avgVal;
  private Long   count;
  // getters, setters and constructor

我想得到如下列表,按 key1、key2、成员计数(count)、val 平均值(avgVal)分组 下面的代码抛出 NullPointerException。

public class Main 
{
  public static void main(String[] args) {
    List<SqlResult> listSqlResult = new ArrayList<>();
    listSqlResult.add(new SqlResult(a1,b1,123));
    listSqlResult.add(new SqlResult(a1,b1,10));
    listSqlResult.add(new SqlResult(a1,b1,23));
    listSqlResult.add(new SqlResult(a1,b2,3));
    listSqlResult.add(new SqlResult(a1,b2,73));
    listSqlResult.add(new SqlResult(a1,b2,15));
    listSqlResult.add(new SqlResult(a2,b1,43));
    listSqlResult.add(new SqlResult(a2,b1,19));
    listSqlResult.add(new SqlResult(a2,b1,15));
    listSqlResult.add(new SqlResult(a2,b2,38));
    listSqlResult.add(new SqlResult(a2,b2,73));
    listSqlResult.add(new SqlResult(a2,b2,15));

    List<Result> listResult = listSqlResult.stream
        .collect(groupingBy(SqlResult::getKey1,
                 groupingBy(SqlResult::getKey2))).values().stream()
        .map(e -> new Result(e.get(0).get(0).getKey1(), e.get(0).get(0).getKey2(),e.get(0).stream().mapToDouble(e::getValue).average(), e.get(0).stream().count()))
    .collect(Collectors.toList())
;

如何使用 Java Stream API 获得统计结果(val 平均值、成员计数)?

【问题讨论】:

    标签: java java-8 java-stream aggregate groupingby


    【解决方案1】:

    您的代码失败的原因是您最终在 Map 上执行了带有 IntegerMap.get 键,而 groupingBy 是在键集中使用 Strings 构造的。因此,查找中对应的 null 值后跟 NPE。

    如果您可以考虑将您的要求分为两个步骤,那就更简单了。一,你总结你手中的数据。其他,您将其映射到您选择的所需结果对象。

    在现有Collectors.summarizing... 的帮助下,这看起来很简单:

    Map<List<String>, DoubleSummaryStatistics> groupedStatistics = listSqlResult.stream()
            .collect(Collectors.groupingBy(sr -> Arrays.asList(sr.getKey1(), sr.getKey2()),
                    Collectors.summarizingDouble(SqlResult::getVal)));
    
    List<Result> results = groupedStatistics.entrySet().stream()
            .map(e -> new Result(e.getKey().get(0), e.getKey().get(1),
                    e.getValue().getAverage(), e.getValue().getCount()))
            .collect(Collectors.toList());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-19
      • 2017-01-26
      • 2015-04-23
      • 2012-02-27
      • 1970-01-01
      • 1970-01-01
      • 2020-07-10
      • 2012-05-07
      相关资源
      最近更新 更多