如何从For循环中制作流

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从For循环中制作流相关的知识,希望对你有一定的参考价值。

我有一个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()短路终端操作来停止处理。

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

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

以上是关于如何从For循环中制作流的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 这个简单的代码片段显示了如何使用有符号整数在C中完成插值。 for()循环确定要插入的范围

在 Activity 内部,如何暂停 for 循环以调用片段,然后在按钮单击片段后恢复循环以重新开始

如何在Django视图中使用for循环返回每次迭代[关闭]

Python中用for循环制作乘法表

如何使用引导程序和 for 循环在 django 中创建电影片段?

我如何在python中使用for循环制作熊猫数据框对象