Читаем Introducing Java 8 полностью

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 = invoices.stream() .filter(inv -> inv.getCustomer() == Customer.ORACLE) .findAny();

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 ids = invoices.stream() .map(Invoice::getId) .collect(Collectors.toList());

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 reduce pattern, it helps to first look at how you could calculate the sum of a list using a for loop: int sum = 0; for (int x : numbers) { sum += x; }

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 to combine two elements and produce a new value. The reduce method essentially abstracts the pattern of repeated application. Other queries such as “calculate the product” or “calculate the maximum” become special-use cases of the reduce method, like so: int product = numbers.stream().reduce(1, (a, b) -> a * b); int max = numbers.stream().reduce(Integer.MIN_VALUE, Integer::max);

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 collect method is a terminal operation. It lets you accumulate the elements of a stream into a summary result.

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> customerToInvoices = invoices.stream().collect(Collectors.groupingBy(Invoice::getCustomer));

Putting It All Together

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже