繁体   English   中英

为什么Stream.limit无法按预期在此代码段中正常工作?

[英]Why doesn't Stream.limit work as expected in this snippet?

List<Integer> integer = Stream.generate(new Supplier<Integer>() {
    int i = 0 ;

    @Override
    public Integer get() {
        return ++i;
    }
}).filter(j -> j < 5)
  .limit(10)   // Note the call to limit here
  .collect(Collectors.toList());

与我的预期相反, collect调用永不返回。 filter产生预期结果之前设置limit 为什么?

由于只有4个元素通过过滤器,所以limit(10)永远不会达到10个元素,因此Stream管道会不断生成新元素并将其馈送到过滤器,以尝试达到10个通过过滤器的元素,但是由于只有第一个4个元素通过过滤器,处理过程永不结束(至少直到i溢出)。

Stream管道不够智能,无法知道没有更多元素可以通过过滤器,因此它会继续处理新元素。

limitfilter子句具有不同的行为。

如果将limit放在首位,则流将首先生成10个整数[1..10],然后对其进行过滤,仅保留小于5的那些整数。

在原始顺序中,首先应用filter ,然后生成并过滤整数,直到达到10个元素。 这不是一个无限运算符,因为供应商中的i最终会溢出,但是要花一些时间(尤其是在速度较慢的计算机上)才能达到MAX_INT

如果您想在达到5或收集10个元素时停止则Java-9中添加了Stream.takeWhile()方法:

List<Integer> integer = Stream.generate(new Supplier<Integer>() {
    int i = 0 ;

    @Override
    public Integer get() {
        return ++i;
    }
}).takeWhile(j -> j < 5).limit(10).collect(Collectors.toList());

在供应商溢出并开始生成负数之后,它将完成。 结果列表将包含:

[1, 2, 3, 4, -2147483648, -2147483647, -2147483646, -2147483645, -2147483644, -2147483643]

原因是在其他答案中。 在我的i7机器上,花了40秒完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM