Существует Stream.iterate
для итерации по бесконечному потоку, который мы можем использовать для создания элементов из start
, которые будут увеличены на blockSize
с использованием некоторого ChronoUnit
.
Сначала продолжайте генерировать (i + 1)
дней в .map(...)
и проверьте, равны ли они beforeEnd
, затем, если это так, добавьте в список blocks.add
, создав new DateBlock(i-1, i)
. Также используйте allMatch()
работу терминала с коротким замыканием, чтобы остановить обработку.
Недостатком здесь является то, что вам нужно проверить beforeEnd
2 раза. В java 9 есть операция .takeWhile
, мысль.
ZonedDateTime start = ZonedDateTime.now();
ZonedDateTime end = ZonedDateTime.now().plusDays(5);
Predicate<ZonedDateTime> beforeEnd = date -> date.isBefore(end);
final long blockSize = 1;
List<DateBlock> blocks = new ArrayList<>();
Stream.iterate(start, d -> d.plus(blockSize, ChronoUnit.DAYS))
.map(d -> d.plus(1, ChronoUnit.DAYS))
.peek(i -> {
if(beforeEnd.test(i))
blocks.add(new DateBlock(i.minus(1, ChronoUnit.DAYS), i));
})
.allMatch(beforeEnd);
Запуск, что я получаю даты, как
[DateBlock{from=2019-04-11...,to=2019-04-12...,
...,
DateBlock{from=2019-04-15...,to=2019-04-16...}]
UPDATE
Я понимаю, что люди говорят, что эта реализация на первый взгляд может показаться неправильной, это только потому, что в java8 нет подходящего метода, просто посмотрите, как элегантно она может выглядеть с .takeWhile
методом.
Predicate<DateBlock> beforeEnd = dateBlock -> dateBlock.to.isBefore(end);
Stream.iterate(start, d -> d.plus(blockSize, ChronoUnit.DAYS))
.map(i -> new DateBlock(i, i.plus(1, ChronoUnit.DAYS)))
.takeWhile(beforeEnd)
.collect(Collectors.toList());