stream values without having to repeat the pipeline of stream operations.
Example 7-18. Using peek to log intermediate values
Set < String > nationalities
= album . getMusicians ()
. filter ( artist -> artist . getName (). startsWith ( "The" ))
. map ( artist -> artist . getNationality ())
. peek ( nation -> System . out . println ( "Found nationality: " + nation ))
. collect ( Collectors .< String > toSet ());
It's also possible to use the peek method to output to existing logging systems such as lo-
g4j , java.util.logging , or slf4j in exactly the same way.
Logging is just one of many tricks that the peek method has up its sleeve. To allow us to de-
bug a stream element by element, as we might debug a loop step by step, a breakpoint can be
set on the body of the peek method.
In this case, peek can just have an empty body that you set a breakpoint in. Some debuggers
won't let you set a breakpoint in an empty body, in which case I just map a value to itself in
order to be able to set the breakpoint. It's not ideal, but it works fine.
▪ Consider how lambda expressions can help when refactoring legacy code: there are com-
▪ If you want to unit test a lambda expression of any complexity, extract it to a regular
▪ The peek method is very useful for logging out intermediate values when debugging.