Generate an infinite Stream<Integer> containing the integers (0, 1, -1, 2, -2, 3, -3, ...)
Something like this:
Stream<Integer> infiniteStream = Stream.iterate(1, i -> i > 0 ? -i : (-i + 1));
Or, if you wish to start with 0
:
Stream<Integer> infiniteStream = Stream.iterate(0, i -> i > 0 ? -i : (-i + 1));
Of course, this can also be done with IntStream
:
IntStream infiniteStream = IntStream.iterate(0, i -> i > 0 ? -i : (-i + 1));
I want to provide an alternative to Erans answer.
Since you already know how the basic infinite stream works, you can use further stream operations like flatMap
to build upon it:
final Stream<Integer> eransAnswer = Stream.iterate(1, i -> i > 0 ? -i : (-i + 1));
final Stream<Integer> alternative = Stream.iterate(1, i -> i + 1)
.flatMap(i -> Stream.of(i, -i));
System.out.println(eransAnswer.limit(6).collect(Collectors.toList()));
System.out.println(alternative.limit(6).collect(Collectors.toList()));
Note that this only works if flatMap
is lazily evaluated. I put the limit
there so that I can collect it in some result (toList
), but it also works with the limit
after the flatMap
.
Sometimes, instead of putting the "complexity" into your generating formula, it may or may not make sense to split it up and use intermediate stream operations. If your thought process is that you alternate numbers, use Erans answer. If you rather think that for the infinite stream of natural numbers, you want to duplicate each number with its inverse, than the intention is conveyed more clearly with the alternative.
EDIT: To handle the Zero, you can do Stream.concat(Stream.of(0), alternative)
If you look a bit closely to the scheme below, it's probably a lot easier than you might think:
0 1 2 3 4 5
| | | | | |
0 1 (-1) 2 (-2) 3
Now, you can look at it this way: if the number is even, the result is that index divided by two (and minus that); if the number is odd, the result is that index divided by two plus 1.
You can tell if the number is odd or even, by simply looking at the last bit: if it is 1
=> odd; if it is 0
=> even. And you can divide a number by two by shifting it to the right once, as such:
IntStream.range(0, 10)
.map(x -> (x & 1) == 0 ? -(x >> 1) : (x >> 1) + 1)
.forEachOrdered(System.out::println);