Reputation: 25385
How do I generate a stream of "new" data? Specifically, I want to be able to create data that includes functions that are not reversible. If I want to create a stream from an Array I do
Stream.of(arr)
col.stream()
A constant stream can be made with a lambda expression
Stream.generate(() -> "constant")
A stream based on the last input (any reversible function) may be achieved by
Stream.iterate(0, x -> x + 2)
But if I want to create a more general generator (say output of whether a number is divisive by three: 0,0,1,0,0,1,0,0,1...) without creating a new class.
The main issue is that I need to have some way of inputing the index into the lambda, because I want to have a pattern, and not to be dependent on the last output of the function.
Note:
someStream.limit(length)
may use to stop the length of the stream, so infinite stream generator is actually what I am looking for.
Upvotes: 1
Views: 1122
Reputation: 298409
If you want to have an infinite stream for a function taking an index, you may consider creating a “practically infinite” stream using
IntStream.rangeClosed(0, Integer.MAX_VALUE).map(index -> your lambda)
resp.
IntStream.rangeClosed(0, Integer.MAX_VALUE).mapToObj(index -> your lambda)
for a Stream
rather than an IntStream
.
This isn’t truly infinite, but there are no int
values to represent indices after Integer.MAX_VALUE
, so you have a semantic problem to solve when ever hitting that index.
Also, when using LongStream.rangeClosed(0, Long.MAX_VALUE).map(index -> yourLambda)
instead and each element evaluation takes only a nanosecond, it will take almost three hundred years to process all elements.
But, of course, there is a way to create a truly infinite stream using
Stream.iterate(BigInteger.ZERO, BigInteger.ONE::add).map(index -> yourLambda)
which might run forever, or more likely, bail out with an OutOfMemoryError
once the index can’t be presented in the heap memory anymore, if your processing ever gets that far.
Note that streams constructed using range[Closed]
might be more effcient than streams constructed using Stream.iterate
.
Upvotes: 4
Reputation: 20544
You can do something like this
AtomicInteger counter = new AtomicInteger(0);
Stream<Integer> s = Stream.generate(() -> counter.getAndIncrement());
Upvotes: 0