Τρίτη, 9 Δεκεμβρίου 2014

Book review: Mastering Lambdas: Java Programming in a Multicore World

Best practices for using Lambda Expressions and Streams
by Maurice Naftalin

"Expensive perfumes come in small bottles" they say.
λ-programming is the new top feature of Java 8 the one that will mostly change the way Java programmers program. While other books on the topic go into describing the new API providing simple examples, Maurice's book follows a more pragmatic way, describing "Best practices for Using Lambda expressions and Streams". The book tackles difficult topics and doesn't provide simple examples to just demonstrate the API usage like other books do. The author tries to introduce the reader on the new way of thinking in a functional way by using his experience in solving complex problems. E.g. he writes an implementation of the UNIX grep command using lambdas and explains how to do it and what errors one has to tackle to achieve their target. He also devotes a whole chapter on streams' performance. He explains the difference between static, bound and unbound instance method references as well as how overloading works. And many more practical problems that someone might come up with while using lambdas and streams.
In more detail:
In Chapter 1 Maurice lays the pillars for the reasoning about these new Java 8 features that will analyse in the rest of his book:
  • from internal to external iteration
  • from collections to streams 
  • from sequential to parallel
He goes into the details of explaining the reasoning behind the design solutions and selected syntax of the above topics convincing the reader of how naturally these changes were introduced into the language.
Chapter 2 is devoted to lambda expressions. It compares lambdas to anonymous inner classes, he talks about variable capture (a.k.a. closures), and moves on to functional interfaces. The sub-chapters are as concise as they should be. He explains the difference between static, bound and unbound instance method references (do you know the difference?) and ends up with (function) type checking and the rules of overloading resolution (both with lambda expressions and method references).
Chapter 3 provides an introduction to streams by comparing them to pipelines. He describes how to start a stream (pipeline), how to transform it (e.g. filtering, mapping, sorting, truncating etc.) and how to end it (e.g. reduce, collect, search etc.). He touches parallelism and debugging. He provides useful and pragmatic examples.
Chapter 4 talks about how to end streams, i.e. about reductions and collections. He also goes into the pain of explaining how to write your own collector. Everything is explained with diagrams on how they work as well as with working examples.
Chapter 5 talks about how to create streams, i.e. sources and spliterators. Here he introduces the worked example of a recursive grep command.
Chapter 6 tackles stream performance. He uses jmh to microbenchmark sequential and parallel streams, sorting, distinct, spliterators, collectors etc. Parallel streams aren't always faster than sequential streams but they must satisfy some conditions to perform better.
Chapter 7, finally, talks about how default methods allow the API to evolve keeping backwards compatibility at the same time.
Small and to the point, all in all a very useful book on the subject, one that you 'll revisit again and again while programming with the new lambdas and stream APIs in Java 8.
Maurice Naftalin is the author of another famous book "Java Generics and Collections" and maintains the lambda FAQ from which he has gained a long experience about the new API. His new book should be under the pillow of every Java developer.