Java IntStream 或 LongStream 按值而不是按元素数限制

wan*_*Dev 3 java java-stream

我想迭代/生成一个无限的 IntStream 或 LongStream 并通过提供的最大值来限制它们,而不是通过操作可能的元素计数limit(long n),例如获得前 20 个正偶数:

List<Integer> evens = IntStream.iterate(0, i -> i + 2)
                               .limit(20)
                               .boxed()
                               .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我需要的是通过最大值限制流。例如,如果我需要 1000 以下的所有 2 次幂

List<Integer> evens = IntStream.iterate(1, i -> i * 2)  //1, 2, 4, 8, 16, 32...
                               .limit(<here some how use the value 1000>)
                               .boxed()
                               .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

或斐波那契数列

List<Long> fibs = Stream.iterate(new long[]{1,1}, f -> new long[]{f[1], f[0] + f[1]})  //1,1,2,3,5,8,13,21...
                        .mapToLong(f -> f[1])
                        .limit(i -> i < 1000) //I know this doesn't work as limit expects a long value
                        .boxed()
                        .collect(Collectors.toList()); 
Run Code Online (Sandbox Code Playgroud)

过滤器不起作用并导致 OutOfMemoryError

List<Integer> evens = IntStream.iterate(1, i -> i * 2)  //1, 2, 4, 8, 16, 32...
                               .filter(i -> i <= 1000)
                               .boxed()
                               .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我有很多不同的UnaryOperators,我想用来生成不同的数字序列(不仅仅是我上面给出的简单例子,比如i -> i * 2我可以以某种方式计算给定范围内元素的可能计数)。

问题:如何通过元素计数的给定最大值限制流?

Lou*_*man 10

在 Java 9+ 中,使用takeWhile(i -> i <= value).


adn*_*n_e 6

你正在寻找 takeWhile

List<Integer> evens = IntStream.iterate(1, i -> i * 2)  //1, 2, 4, 8, 16, 32...
                               .takeWhile(i -> i <= 1000)
                               .boxed()
                               .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)


WJS*_*WJS 5

在您展示的所有案例中,您没有使用iterate()'s允许条件的方法。所以如果有人还没有达到 Java 9,可以这样做:

  • 获得高达 20 的偶数值(包括 20)。
List<Integer> evens = IntStream.iterate(0, i->i<=20, i->i+2)
    .boxed()
    .collect(Collectors.toList());

System.out.println(evens);
Run Code Online (Sandbox Code Playgroud)
  • 得到小于 100 的斐波那契数列
List<Long> fibs = Stream.iterate(new long[]{1,1}, f->f[1] < 100,f -> new long[] 
               {f[1], f[0] + f[1]})
     .mapToLong(f -> f[1])
     .boxed()
     .collect(Collectors.toList());

System.out.println(fibs);
Run Code Online (Sandbox Code Playgroud)
  • 得到 2 的幂,包括 128。
List<Integer> powersOfTwo = IntStream.iterate(1, i-> i <= 128, i -> i * 2)  //1, 2, 4, 8, 16, 32...
        .boxed()
        .collect(Collectors.toList());
    
System.out.println(powersOfTwo);
Run Code Online (Sandbox Code Playgroud)

印刷

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
[1, 2, 4, 8, 16, 32, 64, 128]
Run Code Online (Sandbox Code Playgroud)