It looks like you are trying to implement a recursive relation. The reduce method applies a function to a collection of pre-existing values in a stream. You cannot use reduce and take the intermediate result from the reducer function and “return it back” to the stream, what you need to do to implement the recursive relation.
A way to implement a recursive relationship using streams is to use one of the factory streams of the Stream.generate or Stream.iterate . iterate factory seems to offer the most obvious approach. The state that should be stored for each application of the repeat function requires two integers in your example, so, unfortunately, we need to create an object to store this data for us:
static class IntPair { final int a, b; IntPair(int a_, int b_) { a = a_; b = b_; } }
Using this state object, you can create a thread that implements the required repetition:
Stream.iterate(new IntPair(1, 2), p -> new IntPair(pb, pa * pb))
Once you have such a stream, just collect the values into a list:
List<Integer> output = Stream.iterate(new IntPair(1, 2), p -> new IntPair(pb, pa * pb)) .limit(5) .map(pair -> pair.a) .collect(Collectors.toList()); System.out.println(output); [1, 2, 2, 4, 8]
As an aside, you can use the same method to generate the Fibonacci sequence. All you do is another initial value and an iterative function:
Stream.iterate(new IntPair(0, 1), p -> new IntPair(pb, pa + pb))
You can also implement a similar recursive relation using Stream.generate . This will also require a helper class. The helper class implements the Supplier value of the result, but it must also maintain state. Therefore, it must be volatile, which is rude in my book. The iteration function must also be baked into the generator object. This makes it less flexible than an IntPair object, which can be used to create arbitrary repetitions.