Card 05/ 09
All 9 cards
ExampleDifficulty: Advanced1 min
The Same Four Shapes in a Pipeline That Reads a File
A file of invoice lines, filtered, converted and printed. Each step takes one of the four shapes, and none of them is called a comparator.
Supplier<List<Invoice>> empty = ArrayList::new;
Predicate<String> notBlank = line -> !line.isBlank();
Function<String, Invoice> parse = Invoice::parse;
Consumer<Invoice> print = System.out::println;
List<Invoice> invoices = Files.lines(path)
.filter(notBlank)
.map(parse)
.collect(Collectors.toCollection(empty));
invoices.forEach(print);filter wants something that answers yes or no about one element. map wants something that turns one thing into another. forEach wants something that takes an element and produces nothing. toCollection wants something that produces a collection from nothing.
Put this beside the one-line comparator and the shared fact comes out: in both, the lambda's type came from the parameter it was passed to, and nothing in the lambda itself said what it was. A comparator, a predicate and a function look identical on the page; the method they are handed to is what decides.