如何使用带有对象列表的 java 8 流获取一些统计信息
How can I get some statistics using java 8 stream with object list
我有一个List<SqlResult>
。我需要从 SqlResult 的聚合中得到一个 List<Result>
。例如,
SqlResult(输入)
public class SqlResult{
private String key1;
private String key2;
private Double val;
// getters, setters and constructor
结果数据Class
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流API得到统计结果(val的平均值,成员数)?
您的代码失败的原因是您最终在 groupingBy
期间使用 [=15] 构造的 Map
上执行了 Map.get
和 Integer
键=]s 在键集中。因此,查找中的相应 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());
我有一个List<SqlResult>
。我需要从 SqlResult 的聚合中得到一个 List<Result>
。例如,
SqlResult(输入)
public class SqlResult{
private String key1;
private String key2;
private Double val;
// getters, setters and constructor
结果数据Class
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流API得到统计结果(val的平均值,成员数)?
您的代码失败的原因是您最终在 groupingBy
期间使用 [=15] 构造的 Map
上执行了 Map.get
和 Integer
键=]s 在键集中。因此,查找中的相应 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());