Java – 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

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… here is a solution to the problem.

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.

Related Problems and Solutions