23

I defined natural for Infinite sequence (Stream) of Natural numbers with Java8 iterator.

IntStream natural = IntStream.iterate(0, i -> i + 1);

natural
 .limit(10)
 .forEach(System.out::println);

Now, I want to define it with Java8 generator.

static Stream generate(Supplier s)

What would be the simplest way? Thanks.

  • 2
    What do you mean by generator? Do you mean `Supplier`? – Joffrey Oct 09 '14 at 11:37
  • 1
    Never worked with java 8,but is this what you're looking for http://www.codeproject.com/Articles/793374/Generators-with-Java? – Vinc Oct 09 '14 at 11:43
  • I believe using `Stream.generate(Supplier)` will be more complicated than what you have right now. – Joffrey Oct 09 '14 at 11:47
  • Joffrey, probably `static Stream generate(Supplier s)` , and Vinc, yes I've read the article, but unclear to me somehow. thanks –  Oct 09 '14 at 11:49

3 Answers3

26

With a generator you need to keep track of your current index. One way would be:

IntStream natural = IntStream.generate(new AtomicInteger()::getAndIncrement);

Note: I use AtomicInteger as a mutable integer rather than for its thread safety: if you parallelise the stream the order will not be as expected.

assylias
  • 321,522
  • 82
  • 660
  • 783
  • That's a concise way of doing this without having to create a class, I have to admit. +1. This answer should probably be the accepted one rather than mine. – Joffrey Oct 11 '14 at 09:12
24

This is built into IntStream:

IntStream.range(0, Integer.MAX_VALUE)

This returns all values up to (but not including) Integer.MAX_VALUE.

David Phillips
  • 10,723
  • 6
  • 41
  • 54
13

Note: @assylias managed to do it with a lambda using AtomicInteger. He should probably have the accepted answer.


I'm not sure you can do that with a lambda (because it is stateful), but with a plain Supplier this would work:

IntSupplier generator = new IntSupplier() {
    int current = 0;

    public int getAsInt() {
        return current++;
    }
};

IntStream natural = IntStream.generate(generator);

However, I highly prefer your current solution, because this is the purpose of iterate(int seed, IntUnaryOperator f) IMHO:

IntStream natural = IntStream.iterate(0, i -> i + 1);
Joffrey
  • 32,348
  • 6
  • 68
  • 100
  • It's not infinite, though, is it? ;) -- for most purposes, this would be: ```IntStream.iterate(0, i -> i == Integer.MAX_VALUE ? 0 : i + 1)``` -- I mean, if you just want to keep track of some process and are interested in a window. Otherwise, BigInteger maybe? – Deroude Jun 06 '18 at 13:42
  • @Deroude Good point. Although I guess on a finite computer nothing is really infinite, `BigInteger` will be limited by the available memory at some point. I don't think it really matters in the context of the OP. – Joffrey Feb 06 '20 at 10:15