Questions and Exercises: Aggregate Operations
            
Questions
  - A sequence of aggregate operations is known as a ___ .
- Each pipeline contains zero or more ___ operations.
- Each pipeline ends with a ___ operation.
- What kind of operation produces another stream as its output?
- Describe one way in which the forEachaggregate operation differs from the enhancedforstatement
 or iterators.
- True or False: A stream is similar to a collection in that it 
 is a data structure that stores elements.
- Identify the intermediate and terminal operations in this code:
double average = roster
    .stream()
    .filter(p -> p.getGender() == Person.Sex.MALE)
    .mapToInt(Person::getAge)
    .average()
    .getAsDouble();
- The code 
p -> p.getGender() == Person.Sex.MALE
is an example of what?
- 
The code
Person::getAge
is an example of what?
- 
Terminal operations that combine the contents of a stream and return one value
are known as what?
- 
Name one important difference between the Stream.reducemethod 
and theStream.collectmethod.
- 
If you wanted to process a stream of names, extract the male names, and 
store them in a new List, wouldStream.reduceorStream.collectbe the 
most appropriate operation to use?
- 
True or False: Aggregate operations make it possible to
implement parallelism with non-thread-safe collections.
- 
Streams are always serial unless otherwise specified. How 
 do you request that a stream be processed in parallel?
Exercises
 - 
Write the following enhanced forstatement as a 
pipeline with lambda expressions. Hint: Use thefilterintermediate operation and theforEachterminal 
operation.
 
for (Person p : roster) {
    if (p.getGender() == Person.Sex.MALE) {
        System.out.println(p.getName());
    }
}
- Convert the following code into a new implementation that 
uses lambda expressions and aggregate operations instead of nested
forloops. Hint: Make a pipeline that invokes thefilter,sorted, andcollectoperations, in that order.
List<Album> favs = new ArrayList<>();
for (Album a : albums) {
    boolean hasFavorite = false;
    for (Track t : a.tracks) {
        if (t.rating >= 4) {
            hasFavorite = true;
            break;
        }
    }
    if (hasFavorite)
        favs.add(a);
}
Collections.sort(favs, new Comparator<Album>() {
                           public int compare(Album a1, Album a2) {
                               return a1.name.compareTo(a2.name);
                           }});
Check your answers.