With the release of Java version 8, came the ability to write Lambda expressions, to be used with functional interfaces. Java 8 includes a few functional interfaces, including: Runnable, Callable, Comparator and java.util.function.Predicate, to name a few. For the OCAJP exam you will only need to know how to write a valid Lambda expression for use with the Predicate interface.
What is a Lambda expression? A Lambda expression is essentially functional programming that allows a developer to write short, clear and concise code to replace previously necessary anonymous classes to implement functionality. It is also very useful for preventing duplication in code and for sorting Collections.
In relation to the Predicate interface; Lambda Expressions can be used to evaluate an expression to return a boolean result, which is the datatype the Predicates test() method returns.
The basic building blocks of a Lambda expression are: a) zero or more parameters to pass b) the -> (arrow) that separates the parameters and the boolean expression. c) the expression that must evaluate to either true or false when used with the Predicate interface
and the rules:
1) You can pass zero or more parameters, but when basic zero you must used empty parenthesis (). 2) If passing one parameter no parenthesis or datatype is required. If passing more than two parameters than you must wrap them in parenthesis. 3) If passing more than one parameter and they are of different datatypes, include the datatype declaration. 4) If you are using more than one expression, wrap all expressions in curly braces. 5) If you use the return keyword before the expression, you must include a semi-colon after the expression.
Some examples of valid Predicate Lambda expressions:
What is a functional interface? A functional interface is just a normal interface that has only one single abstract method (SAM). So that it can be used with a Lambda expression, where the Lambda expression is matched with the single interface method. A functional interface can have multiple static and default methods defined, but it can only have one abstract method.
The Predicate interface Java 8 includes a built in functional interface called Predicate which can be used with a Lambda expression and passed into a method, where its test() method can be used in a boolean statement to check a condition. Predicate permits Generics to be used, so that a boolean check can be performed on any datatype.
Here is an example without using Lamba and Predicate: This program is used to sort our list of Dog’s. We can currently sort them by either age, or name. The program works fine as it is but is using duplication for the getDogByAge() and getDogByName() methods, and what if we wanted to sort the list by more attributes or a combination of attributes? The code would soon become verbose, as more and more methods would be needed.
Let’s improve the above code: In the above example, instead of passing the condition parameter into the method, we are passing the Predicate interface of Type Dog. We have gotten rid of the duplicating methods and replaced them with a more generic method, but crucially you will notice that we have removed the conditional check that sorts the list and replaced it with the predicates test() method, which allows us to use any Lambda boolean expression we wish to pass to the method.
So now we can get the same two lists from the first example by just using simple Lambda expressions and the Predicate interface that expects a Dog object, instead of writing specific methods. I have added a third method call, containing a Lambda expression that includes two conditional checks, to demonstrate that we can sort the list based on far more conditions now, using far less code, thanks to functional programming.