3

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

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 平均值、成员计数)?

4

1 回答 1

4

您的代码失败的原因是您最终执行了一个Map.getwithInteger键,Map而不是使用键集中的 sgroupingBy构造的一个String。因此,查找中的相应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());
于 2021-06-09T14:19:38.773 回答