问题
I was reading this book called Modern Java in Action and one part of code I could not comprehend.
IntStream.iterate(0, n -> n + 4)
.filter(n -> n < 100)
.forEach(System.out::println);
Authors says that code will not terminate. The reason is that there’s no way to know in the filter that the numbers continue to increase, so it keeps on filtering them infinitely!
I did not get the reason. Could someone explain it why.
回答1:
You can find the answer in javadocs of IntStream#iterate
:
Returns an infinite sequential ordered IntStream 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.
Now coming to your question, .filter(n -> n < 100)
will filter out only the elements which are more than 100
but the stream won't be terminated since the source is infinite. For terminating a .limit(long n)
should be placed:
IntStream.iterate(0, n -> n + 4)
.limit(100)
.filter(n -> n < 100)
.forEach(System.out::println);
回答2:
Authors says that code will not terminate.
Yes, because this specific overload of iterate
static IntStream iterate(int seed,
IntUnaryOperator f)
Returns an infinite sequential ordered IntStream 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.
returns an infinite stream and given it's an infinite stream it means it can only be terminated via certain operations.
Given the terminal operation in use here (forEach
) is not short-circuiting it means that you require a "short-circuiting intermediate operation" to truncate the infinite stream in this specific case e.g. limit
(JDK8),takeWhile
(JDK9) et al.
The only short-circuiting intermediate operation in JDK8 is limit
as it allows computations on infinite streams to complete in finite time.
The reason is that there’s no way to know in the filter that the numbers continue to increase, so it keeps on filtering them infinitely!
filter
itself is not a short-circuiting intermediate operation hence cannot terminate a stream. filter
's job is essentially to return a stream consisting of the elements of the stream that match the given predicate.
Conclusion: if one is using an infinite stream which does not have a short-circuiting terminal operation then it requires a short-circuiting intermediate operation to truncate the stream else the stream remains infinite.
回答3:
The int stream will generate a sequence of numbers that start from 0 and have step of 4. Then they will be filtered out. The Int keep generating because there is no terminal condition. It equivalent to
for(int n=0;;n=n+4){... Filter out }
来源:https://stackoverflow.com/questions/62286865/intstream-iterate-function-with-filter