如何从 For 循环创建流

大卫·TG

我有一个 for 循环,它通过参数获取值,如果满足某些条件,它会创建一个新的块对象。我需要将此循环转换为 Stream。我搜索了另一个这样的情况,但由于此循环的条件不是迭代器 i 的值,而是日期条件,因此我无法弄清楚如何限制流。此外,这些项目不是预先制作的,就像在其他示例中一样,但它们正在制作中。这是代码:

class DateBlock {    
    final Instant from;
    final Instant to;

    DateBlock(Instant from, Instant to) {
        this.from = from;
        this.to = to;
    }

    public static List<DateBlock> blockize(ZonedDateTime fromDate, 
            ZonedDateTime toDate, 
            int blockSize, 
            ChronoUnit blockSizeUnit) {
        List<DateBlock> blocks = new ArrayList<>();
        boolean reachedDate = false;
        for (int i = 0; !reachedDate; i++) {
            ZonedDateTime minDate = fromDate.plus(i * blockSize, blockSizeUnit);
            ZonedDateTime maxDate = fromDate.plus((i + 1) * blockSize, blockSizeUnit);
            reachedDate = toDate.isBefore(maxDate);
            blocks.add(new DateBlock(minDate.toInstant(), maxDate.toInstant()));
        }

        return blocks;
    }
}

我需要如何进行?

伊沃托维奇

Stream.iterate遍历,我们可以用它来创建从元素的无限流start将由递增blockSize使用一些ChronoUnit

首先,继续生成(i + 1)天数.map(...),并检查它们是否是beforeEnd,如果,则添加到列表blocks.add创建new DateBlock(i-1, i)也可使用allMatch()短路端子操作停止加工。

这里的缺点是你需要检查beforeEnd2次。在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...}]

更新我知道人们说这个实现一开始可能看起来不太好,这只是因为 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());

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章