In addition, the Stream interface provides the operations findFirst and findAny for retrieving arbitrary elements from a stream. They can be used in conjunction with other stream operations such as filter. Both findFirst and findAny return an Optional object (which we discussed in Chapter 1):
Optional
Mapping
Streams support the method map, which takes a Function object as an argument to turn the elements of a stream into another type. The function is applied to each element, “mapping” it into a new element.
For example, you might want to use it to extract information from each element of a stream. This code returns a list of the IDs from a list of invoices:
List
Reducing
Another common pattern is that of combining elements from a source to provide a single value. For example, “calculate the invoice with the highest amount” or “calculate the sum of all invoices’ amounts.” This is possible using the reduce operation on streams, which repeatedly applies an operation to each element until a result is produced.
As an example of a
Each element of the list of numbers is combined iteratively using the addition operator to produce a result, essentially reducing the list of numbers into one number. There are two parameters in this code: the initial value of the sum variable—in this case 0—and the operation for combining all the elements of the list, in this case the addition operation.
Using the reduce method on streams, you can sum all the elements of a stream as shown here: int sum = numbers.stream().reduce(0, (a, b) -> a + b);
The reduce method takes two arguments:
An initial value; here, 0.
A BinaryOperator
Collectors
The operations you have seen so far were either returning another stream (i.e., intermediate operations) or returning a value, such as a boolean, an int, or an Optional object (i.e., terminal operations). By contrast, the
The argument passed to collect is an object of type java.util.stream.Collector. A Collector object essentially describes a recipe for accumulating the elements of a stream into a final result. The factory method Collectors.toList() used earlier returns a Collector object describing how to accumulate a stream into a List. However, there are many similar built-in collectors available, which you can see in the class Collectors. For example, you can group invoices by customers using Collectors.groupingBy as shown here:
Map
Putting It All Together