IntStream iterate in steps

前端 未结 7 1441
悲&欢浪女
悲&欢浪女 2020-12-03 07:41

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

I tried iterate, but this never stops executing.

IntS         


        
相关标签:
7条回答
  • 2020-12-03 08:19

    limit can also be used

    int limit = ( 100 / 3 ) + 1;
    IntStream.iterate(0, n -> n + 3).limit(limit).forEach(System.out::println);
    
    0 讨论(0)
  • 2020-12-03 08:23

    In JDK9 there's takeWhile 1

    IntStream
      .iterate(0, n -> n + 3)
      .takeWhile(n -> n < 100)
      .forEach(System.out::println);
    
    0 讨论(0)
  • 2020-12-03 08:25

    Actually you can also achieve the same results with a combination of peek and 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,

    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:

    Now the same iteration easier to achieve with Java 9:

    Stream.iterate(0, i -> i <= 100, i -> 3 + i).forEach(i -> System.out.printf("%d,", i));
    
    0 讨论(0)
  • 2020-12-03 08:30

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

    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);
    

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

    Note: I am a committer for Eclipse Collections

    0 讨论(0)
  • 2020-12-03 08:32

    More generic solution:

    LongStream.range(0L, (to - from) / step) // +1 depends on inclusve or exclusive
                    .mapToObj(i -> (from + i * step))
                    .collect(Collectors.toList());
    
    0 讨论(0)
  • 2020-12-03 08:37

    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.

    0 讨论(0)
提交回复
热议问题