Use Java Streams to group lists of objects together by attribute and reduce them to a new list of objects with the average of another property
I have a list of SensorSample POJOs
public class SensorSample {
private Device.SensorType sensorType; This is an enum
private double sample;
private long timestamp;
Constructor
Setters
Getters
}
I need to group them by timestamp
so that all SensorSamples
for the same day are together. Then I need to reduce them so that I only have one SensorSample
per day and its sample
value is the average of the sample
code for all objects for that day. Is there a way to do this with Streams?
I’ve put them together so far :
Map<Long, List<SensorSample>> yearSamples = samples.stream()
.collect(groupingBy(sample -> SECONDS_IN_A_DAY*Math.floorDiv(sample.getTimestamp(), SECONDS_IN_A_DAY)));
But I don’t know how to go further.
Solution
I think so. To find the average of a group:
Map<Long, Double> averages = samples.stream()
.collect(groupingBy(SensorSample::getTimestamp,
averagingDouble(SensorSample::getSample)));
I
didn’t expand your formula for the day, I thought it would be more readable if I just called getTimestamp
and omitted the details. If you add the getDay
method to SensorSample
, your code may also be more readable.
Also, if you provide an MCVE, this will be easier to test because it is a bit difficult to test the code above when only one partial class continues.