I need to generate stream of integers that each value is based on the value before according to some math function.
For example - lets say I want to take last number and add 10: [1, 11, 21, 31, 41, ...]
of course the real function is much more complex.
I tried taking the fibonaci example but couldn't make it work:
Stream.iterate(new long[]{ 1, 1 }, p->new long[]{ p[1], p[0]+p[1] })
.limit(92).forEach(p->System.out.println(p[0]));
I can only start at 1.
This is what I tried doing:
Stream.iterate(new long[]{ 1 }, p-> {p[0], p[0] + 10})
.limit(4).forEach(p->System.out.println(p[0]));
We created an infinite stream using an iterate() method. Then we called a limit() transformation and a collect() terminal operation. Then in our resulting List, we will have first 10 elements of an infinite sequence due to a laziness of a Stream.
The other way to get the last element of the stream is by skipping all the elements before it. This can be achieved using Skip function of Stream class. Keep in mind that in this case, we are consuming the Stream twice so there is some clear performance impact.
According to Stream#iterate
method docs:
Returns an infinite sequential ordered Stream produced by iterative application of a function f to an initial element seed, producing a Stream consisting of seed, f(seed), f(f(seed)), etc.
The first element (position 0) in the Stream will be the provided seed. For n > 0, the element at position n, will be the result of applying the function f to the element at position n - 1.
So, for your example, it should work as follows:
Stream.iterate(1L, x -> x + 10L)
.limit(4)
.forEach(System.out::println); // 1 11 21 31
If your function is too complex, you can abstract it to a method:
private long complexFunction(long value) {
return <very_complex_calculation with value>;
}
long N = 4L;
Stream.iterate(1L, this::complexFunction)
.limit(N)
.forEach(System.out::println);
You can use an AtomicLong to keep another variable when iterating. For the Fibonacci sequence where you would keep the largest of the 2 numbers and in the AtomicLong and the iteration variable would be the smallest. E.g.
AtomicLong fibonacci = new AtomicLong(1);
Stream.iterate(1L, x -> fibonacci.getAndAdd(x))
.limit(10)
.forEach(i -> System.out.println(fibonacci.get()));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With