While forEach() sounds like a loop, it is really a terminal operator for streams. Streams cannot be used as the source in a for-each loop to run because they don’t implement the Iterable interface.
edited Table 4.6 segment is attached
Additionally, I see here (and a different 809 book) that forEach() is a terminal operation. Depends maybe? Is the quote and the highly edited Table 4.6 in contradiction with respect to forEach()? Please help me clear my confusion.
I'm not sure what is the contradiction you see. Are you talking about the fact that one talks about a terminal operator, and the other calls it a terminal operation? Those were probably intended to mean the same thing - the correct term is operation.
Or, are you talking about where it says "What happens for infinite streams: Does not terminate"? That's different from being a terminal operation. Terminal means, this operation does not return another stream, and you can't continue to chain additional map(), filter() and collect() methods onto it after this, it's no longer a stream. This implies that, while many other operations are lazy, not actually executing anything on the stream yet... with a terminal operation, there's nothing else to wait for, the stream needs to finally execute all the operations that have been defined for it. A terminal operation is a "Do it!" command, no more waiting.
However, in the special case of an infinite stream... a terminal operation implies that the stream must now start processing. It doesn't imply that it's necessarily possible to stop. If you call forEach() on an infinite stream, it's a terminal operation, so it will start executing the forEach()... (plus any other operations defined for the stream before the forEach...) but it will never end. Unless an exception is thrown. Or you turn off the computer or something. That's what "does not terminate" means.
Do we ever have an infinite stream that doesn't terminate? I now there are things called infinite streams, but don't they eventually find some value which terminates processing? Even if they are called infinite, doesn't that rather mean duration indeterminate?
But it would be correct to say that the terminal operation doesn't terminate the Steam execution.
Campbell Ritchie wrote:Do we ever have an infinite stream that doesn't terminate?
Consider method generate(IntSupplier) of IntStream. Its API documentation says:
The API docs wrote:Returns an infinite sequential unordered stream where each element is generated by the provided IntSupplier. This is suitable for generating constant streams, streams of random elements, etc.
On the other hand IntStream also has a count() method which returns a long value -- it would be interesting to see how it deals with an infinite stream (but not so interesting that I have written the small test program).
posted 1 month ago
These are all infinite streams:
They either go on forever (i.e. until stopped externally somehow), or you modify them to finite streams by adding a takeWhile() or limit(), or something similar. Presumably that was the point of that part of the table, to show which methods could affect an infinite stream.
posted 1 month ago
Mike Simmons wrote:. . . takeWhile() . . .
I was very pleased that they completed Streams with takeWhile() and skipWhile(), which were obviously missing before that.
Presumably that was the point of that part of the table, to show which methods could affect an infinite stream.
I was a little worried when I saw the subject of this thread. We put a lot of effort into making this table clearer. (The version of it in the Java 8 book was confusing). I'm glad the point of confusion here was at least something else!