. count ();
So, if you ran Example 3-6 with the members of The Beatles as your list of artists, then you
would see Example 3-7 printed out on your command line.
Example 3-7. Sample output showing the members of The Beatles being printed
It's very easy to figure out whether an operation is eager or lazy: look at what it returns. If it
gives you back a Stream , it's lazy; if it gives you back another value or void , then it's eager.
This makes sense because the preferred way of using these methods is to form a sequence of
lazy operations chained together and then to have a single eager operation at the end that
generates your result. This is how our counting example operates, but it's the simplest case:
only two operations.
This whole approach is somewhat similar to the familiar builder pattern. In the builder pat-
tern, there are a sequence of calls that set up properties or configuration, followed by a single
call to a build method. The object being created isn't created until the call to build occurs.
I'm sure you're asking, “Why would we want to have the differentiator between lazy and
eager options?” By waiting until we know more about what result and operations are needed,
we can perform the computations more efficiently. A good example is finding the first num-
ber that is > 10 . We don't need to evaluate all the elements to figure this out—only enough
to find our first match. It also means that we can string together lots of different operations
over our collection and iterate over the collection only once.
Common Stream Operations
At this point, it's worth just having a look back at some common Stream operations in order
to get more of a feel of what's available in the API. As we will cover only a few important
examples, I recommend looking at the Javadoc for the new API to see what else is available.