Java Reference
In-Depth Information
executes in parallel would be a lot more difficult to write (see section 7.2 in the previous chapter
about the fork/join framework to get an idea):
List<String> dishNames = new ArrayList<>();
for(Dish dish: menu){
if(dish.getCalories() > 300){
dishNames.add(dish.getName());
}
}
The alternative using the Streams API reads more like the problem statement, and it can be
easily parallelized:
menu.parallelStream()
.filter(d -> d.getCalories() > 300)
.map(Dish::getName)
.collect(toList());
Unfortunately, converting imperative code to the Streams API can be a difficult task, because
you need to think about control-flow statements such as break, continue, and return and infer
the right stream operations to use. The good news is that some tools can help you with this task
as well. [ 2 ]
2 See http://refactoring.info/tools/LambdaFicator/ .
8.1.5. Improving code flexibility
We argued in chapters 2 and 3 that lambda expressions encourage the style of behavior
parameterization . You can represent multiple different behaviors with different lambdas that
you can then pass around to execute. This style lets you cope with requirement changes (for
example, creating multiple different ways of filtering with a Predicate or comparing with a
Comparator). We now look at a couple of patterns that you can apply to your codebase to
immediately benefit from lambda expressions.
Adopting functional interfaces
First, you can't use lambda expressions without functional interfaces. You should therefore start
introducing them in your codebase. That sounds good, but in which situations? We discuss two
common code patterns that can be refactored to leverage lambda expressions: conditional
 
Search WWH ::




Custom Search