java IntStream 逐步迭代

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40358827/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 05:09:10  来源:igfitidea点击:

IntStream iterate in steps

javafunctional-programmingjava-8

提问by JasperJ

How do you iterate through a range of numbers (0-100) in steps(3) with IntStream?

如何使用 IntStream 在步骤 (3) 中迭代一系列数字 (0-100)?

I tried iterate, but this never stops executing.

我试过了iterate,但这永远不会停止执行。

IntStream.iterate(0, n -> n + 3).filter(x -> x > 0 && x < 100).forEach(System.out::println)

采纳答案by JasperJ

Actually rangeis ideal for this.

实际上range是理想的。

IntStream.range(0, 100).filter(x -> x % 3 == 0); //107,566 ns/op [Average]


Edit: Holgers's solution is the fastest performing solution.

编辑:Holgers 的解决方案是性能最快的解决方案。

Since the following lines of code

由于以下代码行

IntStream.range(0, 100).filter(x -> x % 3 == 0).forEach((x) -> x = x + 2); 

IntStream.range(0, 100 / 3).map(x -> x * 3).forEach((x) -> x = x + 2); 

int limit = ( 100 / 3 ) + 1; 
IntStream.iterate(0, n -> n + 3).limit(limit).forEach((x) -> x = x + 2);

show these benchmark results

显示这些基准测试结果

Benchmark                 Mode  Cnt    Score    Error  Units
Benchmark.intStreamTest   avgt    5  485,473 ± 58,402  ns/op
Benchmark.intStreamTest2  avgt    5  202,135 ±  7,237  ns/op
Benchmark.intStreamTest3  avgt    5  280,307 ± 41,772  ns/op

回答by gil.fernandes

Actually you can also achieve the same results with a combination of peek and allMatch:

实际上,您也可以通过 peek 和 allMatch 的组合获得相同的结果:

IntStream.iterate(0, n -> n + 3).peek(n -> System.out.printf("%d,", n)).allMatch(n -> n < 100 - 3);

This prints

这打印

0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,

0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72, 75,78,81,84,87,90,93,96,99,

But nevertheless, this one is faster:

但是,这个速度更快:

IntStream.range(0, 100 / 3 + 1).map(x -> x * 3).forEach((x) -> System.out.printf("%d,", x));

Java 9 Update:

Java 9 更新:

Now the same iteration easier to achieve with Java 9:

现在使用 Java 9 更容易实现相同的迭代:

Stream.iterate(0, i -> i <= 100, i -> 3 + i).forEach(i -> System.out.printf("%d,", i));

回答by davidsheldon

In JDK9 there's takeWhile1

在 JDK9 中有takeWhile1

IntStream
  .iterate(0, n -> n + 3)
  .takeWhile(n -> n < 100)
  .forEach(System.out::println);

回答by Saravana

limitcan also be used

limit也可以使用

int limit = ( 100 / 3 ) + 1;
IntStream.iterate(0, n -> n + 3).limit(limit).forEach(System.out::println);

回答by Donald Raab

If you are ok adding a library dependency, the IntIntervalclass in Eclipse Collectionshas the step function I think you are looking for. I tried a few different approaches converting IntIntervalto an IntStream, since the original question asked for IntStream. Here are the solutions I came up with using IntIntervaland then converting it to an IntStream.

如果您可以添加库依赖项,那么Eclipse Collections 中IntInterval类具有我认为您正在寻找的 step 函数。我尝试了几种不同的转换为 an 的方法,因为最初的问题要求. 这是我想出的解决方案,然后将其转换为.IntIntervalIntStreamIntStreamIntIntervalIntStream

IntInterval interval = IntInterval.zeroTo(99).by(3);
interval.each(System.out::print);

IntStream.of(interval.toArray()).forEach(System.out::print);

IntStream.Builder builder = IntStream.builder();
interval.each(builder::add);
builder.build().forEach(System.out::print);

IntStream.generate(interval.intIterator()::next)
    .limit(interval.size()).forEach(System.out::print);

IntIntervalis inclusive on the from and to like IntStream.rangeClosed().

IntInterval是包容对 from 和 to 喜欢IntStream.rangeClosed()

Note: I am a committer for Eclipse Collections

注意:我是 Eclipse Collections 的提交者

回答by Sriram

Elegant Solution:

优雅的解决方案:

IntStream.iterate(0, n -> n < 100, n -> n + 3).forEach(System.out::println)

Stream.iterate() supports a hasNext()predicate(added in Java 9) which can be used to limit the stream in more natural way.

Stream.iterate() 支持hasNext()谓词(在 Java 9 中添加),可用于以更自然的方式限制流。

回答by gstackoverflow

More generic solution:

更通用的解决方案:

LongStream.range(0L, (to - from) / step) // +1 depends on inclusve or exclusive
                .mapToObj(i -> (from + i * step))
                .collect(Collectors.toList());