I am currently creating a Map<String, Map<LocalDate, Integer>> like this, where the Integer represents seconds:
Map<String, Map<LocalDate, Integer>> map = stream.collect(Collectors.groupingBy(
            x -> x.getProject(),
            Collectors.groupingBy(
                x -> x.getDate(),
                Collectors.summingInt(t -> t.getDuration().toSecondOfDay())
            )
        ));
How could I instead create a Map<String, Map<LocalDate, Duration>>?
To change that Integer from Collectors.summingInt to a Duration, you simply need to replace that Collector with: 
Collectors.collectingAndThen(
    Collectors.summingInt(t -> t.getDuration().toSecondOfDay()),
    Duration::ofSeconds
)
                        If you were using an actual Duration for getDuration() (instead of LocalTime), you could also sum directly the Duration's as follows:
Map<String, Map<LocalDate, Duration>> map = stream.collect(Collectors.groupingBy(
        MyObject::getProject,
        Collectors.groupingBy(
                MyObject::getDate,
                Collectors.mapping(MyObject::getDuration,
                        Collectors.reducing(Duration.ZERO, Duration::plus))
        )
));
With the advantage that it also sums the nanoseconds, and could be generalized to other types as well.
Note however that it creates many intermediate Duration instances which could have an impact on the performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With