This tutorial is a preparation material for OCAJP certification exam. This covers the objective 9.5 in the OCAJP 8 exam topics (Write a simple Lambda expression that consumes a Lambda Predicate expression). The mock exams that would appear on the real exams could be simpler than the sample mock exams in this tutorial.
Java is purely object oriented programming. Java treats everything in the form of object. Functions are not given the highest importance in Java programming, thanks to the popularity of the functional programmings like JavaScript. Java 8 takes the first step towards introducing the functional programming with Lambda expressions.
Lambda Expressions
Some of the key points about the lambda expressions.
- There is no need to declare the type of the parameters, compiler can implicitly decide the type from the value of the parameters.
- There is no need to use parenthesis for a single parameter. If we are using the multiple parameters, then it should be enclosed with parenthesis.
- If the lambda expression body contains a single statement, then there is no need to use the curly braces for the statement block. It is required if there is more than one statements in the block.
- Lambda expressions are introduced primarily to define inline implementation of a functional interfaces i.e. an interface with a single abstract method only.
- Lambda expression replaces the need of anonymous class and gives a very simple and powerful functional programming capability to Java programming language.
In Java, before Java 8 version the syntax for using the anonymous class as below:
package javabeat.net; public class AnonymousExample { public static void main(String[] args) { SomeListener listener = new SomeListener() { @Override public void action() { System.out.println("Action Performed"); } }; listener.action(); } } interface SomeListener { void action(); }
If you look at the above code, SomeListener is a functional interface (because it declares only one abstract method) and used as anonymous class in the example. We have to declare the inline implementation of that class for creating the instance that will used for calling the methods action(). The above code could be simplified using the lambda expressions as below:
package javabeat.net; public class AnonymousExample{ public static void main(String[] args) { SomeListener listener = () -> System.out.println("Action Performed"); listener.action(); } } interface SomeListener { void action(); }
Lambda expression has three parts.
- Argument List is the parameters of the method. This method must match the parameters in the target functional interface. Also type of the parameters can be omited.
- Arrow Token informs compiler that this expression is a lambda notation and parse it accordingly.
- Body is the actual implementation of the functional method. Either this could be a single expression, single statement without a curly braces or multiple statements with curly braces.
Predicate with Lambda Expression
Predicate is a functional interface introduced as part of the Java 8 version under the package java.util.function. The following are some of the key points about the Predicate interface.
- Predicate is used for assigning a lambda expression.
- It is a functional interface.
- Predicate interface defines 4 default methods and one functional method(abstract method).
- Predicates represents single argument functions that return a boolean value.
- Predicates can be chained together using and, or and negate to filter the data.
- Four methods in the Predicate interface is and, or, isEqual, negate and test.
- test(T t) in the predicate interface returns the boolean value
Here is a simple example that demonstrates the power of using predicate with lambda expressions.
package javabeat.net; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; public class PredicateExample { public static void main(String[] args) { Child child1 = new Child(3); Child child2 = new Child(2); Child child3 = new Child(7); Child child4 = new Child(10); Child child5 = new Child(6); Child child6 = new Child(9); Child child7 = new Child(8); List<Child> childs = Arrays.asList(new Child[] { child1, child2, child3, child4, child5, child6, child7 }); List<Child> filtered = ChildPredicates.filterChilds(childs, ChildPredicates.filterByAge(8)); for (Child child : filtered) { System.out.println(child.getAge()); } } } class ChildPredicates { static Predicate<Child> filterByAge(int x) { return a -> a.getAge() > x; } static List<Child> filterChilds(List<Child> childs, Predicate<Child> predicate) { return childs.stream().filter(predicate) .collect(Collectors.<Child> toList()); } } class Child { int age; public Child(int age) { this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
In the above example, we are creating predicates for filtering the child with condition as age. If we don’t have the feature of the predicate and lambda, we may have to write the logic for checking the each condition and write a method. Also stream API provide the filter() method that takes the predicate as argument and evaluate the lambda expression.
Sample Mock Exam For Lambda Expressions and Predicate
1. What will be the output of the below program?
package javabeat.net; public class LambdaMock1 { static final int k = 20; interface Inter{ int method(int x); } public static void main(String[] args) { Inter inter = (x) -> k + 10; System.out.println(inter.method(20)); } }
Answers are:
- compiler error
- 30
- If you remove final keyword for variable k, the program will compile fine
- None of the above
Correct Answer : 30
Explanation:
- Final variable can be accessed inside a lambda expression
- There is no error in the lambda syntax in the above program
2. Which of the following are valid syntax for lambda expressions?
- () -> System.out.println(“Lambda”);
- () -> {System.out.println(“Lambda”);};
- () <- System.out.println();
- () <- {System.out.println();};
Correct Answer : 1,2
Explanation: The correct notation for lambda expression is ->. 1 & 2 uses the correct notaion with curly braces and wothout curly braces.
3. Return keyword in lambda expression is optional when body has a single expression to return the value. State whether the above statements are true?
- True
- False
Correct Answer: 1
Explanation: Compiler automatically returns value if body has a single expression to return the value. Curly Braces are required to indicate that expression returns a value.
4. Predicate is not a functional interface. Is the above statement true/false?
- True
- False
Correct Answer: 2. False
Explanation: Predicate is a functional interface
5. State that if the below statement is correct in syntax.Assume that s is not delcared anywhere in the program.
Predicate predicate = (s)->s.equals(“string”);
- Incorrect. There will be complier error (s is not delclared)
- The above statement would compile and run without any error.
Correct Answer: 2
Explanation: The above statement would compile and run without any error. It is a lambda expression and we need not declare the variable s since it is used inside lambda expressions.
6. What is the return type of the method test(T t) in the Predicate functional interface?
- char
- boolean
- String
- int
Correct Answer: 2
Explanation: test(T t) is abstract method in the Predicate interface and returns the boolean type.
7. What will be the output for the below program:
package javabeat.net; import java.util.function.Predicate; public class PredicateExample { public static void main(String[] args) { Predicate<Integer> greaterThanTen = (var) -> var > 10; System.out.println(greaterThanTen.test(10)); } }
- true
- false
- compiler error
- run time exception
Correct Answer: false
Explanation: This program will cimpile properly and evaluate the lambda expression to check if it is greater than 10 for value passed as argument.