Подтвердить что ты не робот

Как получить пользовательский тип вместо Integer при использовании Collectors.summingInt?

В настоящее время я создаю Map<String, Map<LocalDate, Integer>>, где Integer представляет секунды:

Map<String, Map<LocalDate, Integer>> map = stream.collect(Collectors.groupingBy(
            x -> x.getProject(),
            Collectors.groupingBy(
                x -> x.getDate(),
                Collectors.summingInt(t -> t.getDuration().toSecondOfDay())
            )
        ));

Как я мог вместо этого создать Map<String, Map<LocalDate, Duration>>?

4b9b3361

Ответ 1

Чтобы изменить этот Integer с Collectors.summingInt на Duration, вам просто нужно заменить это Collector на:

Collectors.collectingAndThen(
    Collectors.summingInt(t -> t.getDuration().toSecondOfDay()),
    Duration::ofSeconds
)

Ответ 2

Если вы использовали фактический Duration для getDuration() (вместо LocalTime), вы могли бы также непосредственно суммировать Duration следующим образом:

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))
        )
));

С тем преимуществом, что он также суммирует наносекунды и может быть обобщен и на другие типы.

Обратите внимание, что он создает много промежуточных экземпляров Duration, которые могут повлиять на производительность.