首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无限流与过滤

无限流与过滤
EN

Stack Overflow用户
提问于 2014-08-06 17:57:08
回答 1查看 1.4K关注 0票数 3

我对Java8StreamAPI并不熟悉,实际上我不明白为什么我的代码不能工作:

代码语言:javascript
复制
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Stream.iterate(0, x -> x+3)
                                        .filter(x -> x>10 && x<100).peek(System.out::println)
                                        .collect(Collectors.toList());
        numbers.forEach(System.out::println);
    }
}

当我理解溪流的“懒惰”时,我写道:

  1. 创建数字可被3整除的流
  2. 过滤它,给我一个从范围(10,100)的数字流。
  3. 将此流收集到列表中

正如我所看到的,无穷大循环有一些问题,所以peek()从范围(12,99)打印数字是可以的,但是在那之后,它再次打印来自(11,98)的数字等等。你能解释我在哪里出错了吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-06 18:00:13

编译器和运行时都不知道filter会过滤掉100以上的所有数字。因此,运行库继续生成无限个整数,并将筛选器应用于它们。

您有多种解决此问题的方法:

使用limit将无限流截断为有限流。这使得下面的过滤器有点不必要(如果您设置了一个严格的限制,那么只有x>10测试仍然相关)。

代码语言:javascript
复制
public static void main(String[] args) {
    List<Integer> numbers = Stream.iterate(0, x -> x+3)
                                    .limit(34)
                                    .filter(x -> x>10 && x<100).peek(System.out::println)
                                    .collect(Collectors.toList());
    numbers.forEach(System.out::println);
}

使用IntStream.range并乘以3:

代码语言:javascript
复制
public static void main(String[] args) {
    List<Integer> numbers = IntStream.range(0, 34)
                                    .map(x -> 3*x)
                                    .collect(Collectors.toList());
    numbers.forEach(System.out::println);
}

一般来说,流的“懒惰”意味着它们只有在遇到终端(最终)操作时才开始执行。如果操作需要处理列表中的所有元素(如toList ),则不应将其传递为无限流。

当您处理无限流时,您的选项是将其截断为有限流(使用限制),或者有一个不需要处理流的所有元素的终端操作(例如: anyMatch、findFirst、findAny)。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25167000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档