I have a List<SqlResult>
. I need to get a List<Result>
from the aggregation of SqlResult. For example,
SqlResult(Input)
public class SqlResult{
private String key1;
private String key2;
private Double val;
// getters, setters and constructor
Result Data Class
public class Result{
private String key1;
private String key2;
private Double avgVal;
private Long count;
// getters, setters and constructor
I want get List like below, group by with key1, key2, count of members(count), average of val(avgVal) Below code throw 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())
;
How can I get statistical results (average of val, count of member) using Java Stream API?
The cause for your code failing is that you end up performing a
Map.get
withInteger
key over aMap
which duringgroupingBy
was constructed withString
s in keyset. Hence the correspondingnull
value in lookup followed by an NPE.It would be simpler if you could think of formulating your requirements into two steps. One, where you summarise the data that is in your hand. Other, where you map it to the desired result object of your choice.
With the help of existing
Collectors.summarizing...
, this could look as simple as the following: