Использование потоков для суммирования коллекции неизменяемых объектов `Duration`, в Java - PullRequest
2 голосов
/ 23 марта 2020

Класс java.time.Duration, встроенный в Java 8 и более поздние версии, представляет промежуток времени, не привязанный к шкале времени в шкале часов-минут-секунд. Класс предлагает plus метод для суммирования двух таких отрезков времени.

Классы java .time используют неизменяемые объекты. Таким образом, метод Duration::plus возвращает новый третий Duration объект в результате, а не изменяет (мутирует) любой из входных объектов.

Обычный синтаксис для суммирования коллекции Duration объекты будут следующими:

Duration total = Duration.ZERO;
for ( Duration duration : durations )
{
    total = total.plus( duration );
}

Могут ли потоки использоваться вместо этого for l oop?

Ответы [ 3 ]

8 голосов
/ 23 марта 2020

Этого можно достичь, используя перегруженный метод Stream#reduce, который принимает идентификатор:

durations.stream().reduce(Duration.ZERO, Duration::plus)

В следующем фрагменте приведен пример:

var durations = List.of(Duration.ofDays(1), Duration.ofHours(1));
System.out.println(durations.stream().reduce(Duration.ZERO, Duration::plus));

Как и ожидалось, на выходе будет:

PT25H
4 голосов
/ 23 марта 2020

Да, вы можете использовать операцию reduce с элементом идентификации как

Duration total = durations.stream()
        .reduce(Duration.ZERO, Duration::plus);
2 голосов
/ 23 марта 2020

Вот полностью рабочий пример с примерами ввода. Вам нужно использовать функцию Reduce в java потоках. Вот краткое руководство по , которое я использовал.

import java.time.Duration;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class DurationTest {
    public static void main(String [] args){
        List<Duration> durations = IntStream
                .rangeClosed(1, 10)
                .mapToObj( n -> Duration.ofSeconds(n) )
                .collect(Collectors.toList());

        int sumOfSeconds = (10 * (1 + 10) ) / 2;

        Duration total = durations.stream().reduce( Duration.ZERO, (t, d) -> t = t.plus(d) );
        System.out.printf("actual = %s, expected = %s", total.getSeconds(), sumOfSeconds);
    }
}
...