A sliding window overlaps, so it cannot be a groupingBy. Stream the end index instead and take a subList behind it - and format with Locale.ROOT so the report reads the same on every machine.
record Reading(int at, double celsius) {}
var readings = List.of(new Reading(1, 20.0), new Reading(2, 22.0), new Reading(3, 24.0),
new Reading(4, 30.0), new Reading(5, 26.0));
int size = 3;
IntStream.rangeClosed(size - 1, readings.size() - 1)
.mapToObj(i -> {
double avg = readings.subList(i - size + 1, i + 1).stream()
.mapToDouble(Reading::celsius).average().orElse(0);
return String.format(Locale.ROOT, "at %ds avg(%d) = %.2f", readings.get(i).at(), size, avg);
})
.forEach(System.out::println);
at 3s avg(3) = 22.00
at 4s avg(3) = 25.33
at 5s avg(3) = 26.67
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-09-20