IntStream iterate function with filter

家住魔仙堡 提交于 2020-06-12 08:40:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!