The assembly line consists of several methods. Each method takes the data, transforms the data in some way or other, and hands its results to the next method in line. Here’s an assembly line.
Each box represents a bunch of raw materials as they're transformed along an assembly line. Each arrow represents a method (or, metaphorically, a worker on the assembly line).
For example, in the transition from the second box to the third box, a worker method (the filter
method) sifts out sales of items that aren't DVDs. Imagine Lucy Ricardo standing between the second and third boxes, removing each book or CD from the assembly line and tossing it carelessly onto the floor.
The parameter to Java's filter
method is a Predicate
— a lambda expression whose result is boolean
. The filter
method sifts out items that don't pass the lambda expression's true / false
test.
Method Name | Member Of | Parameter(s) | Result Type | Result Value |
stream |
Collection (for example, an ArrayList , object) |
(none) | Stream |
A stream that spits out elements of the collection |
filter |
Stream |
Predicate |
Stream |
A new stream containing values for which the lambda expression returns true |
map |
Stream |
Function |
Stream |
A new stream containing the results of applying the lambda expression to the incoming stream |
reduce |
Stream |
BinaryOperator |
The type used by the BinaryOperator |
The result of combining all the values in the incoming stream |
map
method) pulls the price
out of each sale
. From that worker's place onward, the assembly line contains only price
values.To be more precise, Java's map
method takes a Function
such as
(sale) -> sale.getPrice()
and applies the Function
to each value in a stream. So the map
method takes an incoming stream of sale
objects and creates an outgoing stream of price
values.
In the transition from the fourth box to the fifth box, a worker method (the reduce
method) adds up the prices of DVD sales. Java's reduce
method takes two parameters:
The first parameter is an initial value.
In the image above, the initial value is 0.0
.
The second parameter is a BinaryOperator
.
In the image above, the reduce
method's BinaryOperator
is
(price1, price2) -> price1 + price2
The reduce
method uses its BinaryOperator
to combine the values from the incoming stream. The initial value serves as the starting point for all the combining. So, the reduce
method does two additions.
For comparison, imagine calling the method
reduce(10.0, (value1, value2) -> value1 * value2)
with the stream whose values include 3.0
, 2.0
, and 5.0
. The resulting action is shown below
You might have heard of Google's MapReduce programming model. The similarity between the programming model's name and the Java method names map
and reduce
is not a coincidence.
import java.text.NumberFormat;
import java.util.ArrayList;
public class TallySales {
public static void main(String[] args) {
ArrayList<Sale> sales = new ArrayList<>();
NumberFormat currency = NumberFormat.getCurrencyInstance();
fillTheList(sales);
<strong> </strong>
<strong>double total = sales.stream()</strong>
<strong>.filter((sale) -> sale.getItem().equals("DVD"))</strong>
<strong>.map((sale) -> sale.getPrice())</strong>
<strong>.reduce(0.0, (price1, price2) -> price1 + price2);</strong>
System.out.println(currency.format(total));
}
static void fillTheList(ArrayList<Sale> sales) {
sales.add(new Sale("DVD", 15.00));
sales.add(new Sale("Book", 12.00));
sales.add(new Sale("DVD", 21.00));
sales.add(new Sale("CD", 5.25));
}
}
The code requires Java 8 or later. If your IDE is set for an earlier Java version, you might have to tinker with the IDE's settings. You may even have to download a newer version of Java.
The boldface is one big Java assignment statement. The right side of the statement contains a sequence of method calls. Each method call returns an object, and each such object is the thing before the dot in the next method call. That's how you form the assembly line.For example, near the start of the boldface code, the name sales
refers to an ArrayList
object. Each ArrayList
object has a stream
method. In the code above, sales.stream()
is a call to that ArrayList
object's stream
method.
The stream method returns an instance of Java's Stream
class. (What a surprise!) So sales.stream()
refers to a Stream
object.
Every Stream
object has a filter
method. So
sales.stream().filter((sale) -> sale.getItem().equals("DVD"))
is a call to the Stream
object's filter
method.
The pattern continues. The Stream
object's map
method returns yet another Stream
object — a Stream
object containing prices.
To that Stream
of prices you apply the reduce
method, which yields one double
value — the total of the DVD prices.