In this post we will going to discuss about what is lambda expression in java?. How to use them?. How it helps developers?. All this question will be answered end of this post.
Before we start answering this question, let we look in to some implementation to get 10+years experience employee from list of employee object.
Here coding snippet:
public class Employee {
private int id;
private String name;
private double experience;
private long salary;
private int rating;
public Employee(int id, String name, double experience, long salary, int rating) {
this.id = id;
this.name = name;
this.experience = experience;
this.salary = salary;
this.rating = rating;
}
//Getter and Setter here
}
Here my implementation class to print 10+years experience employee.
public static void main(String[] args) {
Employee employee1 = new Employee(5, "Antwaun", 5.5, 10000L, 1);
Employee employee2 = new Employee(2, "Rick", 32.5, 2000L, 3);
Employee employee3 = new Employee(1, "Richard", 50, 3000L, 4);
Employee employee4 = new Employee(3, "Corey", 22.5, 20000L, 2);
Employee employee5 = new Employee(4, "Chumlee", 10.5, 15000L, 5);
List<Employee> employeeList = new ArrayList<>();
employeeList.add(employee1);
employeeList.add(employee2);
employeeList.add(employee3);
employeeList.add(employee4);
employeeList.add(employee5);
printEmployeeExpGreaterTenYears(employeeList);
}
public static void printEmployeeExpGreaterTenYears(List<Employee> employeeList){
for(Employee employee: employeeList){
if(employee.getExperience() >= 10){
System.out.println(employee);
}
}
}
Output:
Employee{id=2, name='Rick', experience=32.5, salary=2000, rating=3}
Employee{id=1, name='Richard', experience=50.0, salary=3000, rating=4}
Employee{id=3, name='Corey', experience=22.5, salary=20000, rating=2}
Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}
This looks good. we are iterating list and check the experience grater or equals to 10. If in future the requirement change like we need to get 10+ experience and rating will be more than 4+. So then we need to change the existing logic or else we need to write a new method with two param.
Let see the implementation,
public static void printEmployeeExpGreaterTenYearsAndSalaryPassed(
List<Employee> employeeList, int rating){
for(Employee employee: employeeList){
if(employee.getExperience() >= 10 && employee.getRating() >= rating){
System.out.println(employee);
}
}
}
These condition may be change in future. Like employee salary, employee name or we may add some new variable in Employee class. So its not good to change existing logic or add new logic when we have new enhancement to be implement.
So what else we can do?? .. Let think about Functional Interface in java 8.
- Functional interface, which have only one abstract method and any number of default method.
Let we create a Function interface with one abstract method. Interface name CheckEmployee for now have method name test().
public interface CheckEmployee {
boolean test(Employee employee);
}
Here we need to implement this test method, so I have created CheckEmployeeService class.
public class CheckEmployeeService implements CheckEmployee {
@Override
public boolean test(Employee employee) {
return (employee.getExperience() >= 10 && employee.getRating() >= 4);
}
}
Let add a method to printEmployee in out Impl class.
public static void printPersons(
List<Employee> employeeList, CheckEmployee checkEmployee){
for(Employee employee: employeeList){
if(checkEmployee.test(employee)){
System.out.println(employee);
}
}
}
Now we can call this printPersons method from main method,
printPersons(employeeList, new CheckEmployeeService());
Output:
Employee{id=1, name='Richard', experience=50.0, salary=3000, rating=4}
Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}
Its looks good. but we have created a Interface and Service class, that's not necessary we can create them inside the Impl class itself.
As already said CheckPerson interace is Functional interface. Because it has one and only abstract method. Java provide lambda operation for functional interface. We can use lambda expression on functional interface.
Let see how we can use them,
printPersons(employeeList, new CheckEmployeeService());
System.out.println("Lambda expression ");
printPersons(employeeList,
(Employee employee) -> employee.getExperience() >= 10 && employee.getRating() >= 4);
Output:
Employee{id=1, name='Richard', experience=50.0, salary=3000, rating=4}
Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}
Lambda expression
Employee{id=1, name='Richard', experience=50.0, salary=3000, rating=4}
Employee{id=4, name='Chumlee', experience=10.5, salary=15000, rating=5}
Now you might get idea of how do we use lambda expression in java 8. In Functional interface we can use lambda expression. By using lambda expression it reduces the coding effort. Java provide many Functional interface, they all available in java.util.function
For example we can use you can use the Predicate<T>
interface in place of CheckEmployee
. This interface contains the method boolean test(T t).
Let see how to use predicate interface instead of CheckEmployee.
public static void printEmployeesWithPredicate(
List<Employee> roster, Predicate<Employee> tester) {
for (Employee p : roster) {
if (tester.test(p)) {
System.out.println(p);
}
}
}
call from main method,
printEmployeesWithPredicate(employeeList,
(Employee employee) -> employee.getExperience() >= 10 && employee.getRating() >= 4);
This will print the same output ass like what we have printed by using CheckEmployee interface. So far we have answered what is lambda expression, how to use them and how it helps developer to reduce the coding effort. I hope this will give some basic and deep understanding of lambda expression.
There are lot of Functional interface we have in java. Please go through the JavaDoc . So When we are speaking about lambda expression you might think of Steams.. Are you??. Okay. Let see how to we use Stream to printPersion.
Classes to support functional-style operations on streams of elements,
such as map-reduce transformations on collections. - JavaDoc .
Stream support functional style operation on stream element. Let we use stream element to printPersons. Here code snippet.
employeeList
.stream()
.filter(
employee -> employee.getExperience() >= 10 && employee.getRating() >= 4)
.forEach(employee -> System.out.println(employee));
This will print the same output ass like what we have printed by using CheckEmployee interface.
I hope this will give some basic and deep understanding of lambda expression and stream.
Thank you all.
Consolidated Coding snippet.
package com.example.monitoring.lambda;
import com.example.monitoring.compare.CheckEmployee;
import com.example.monitoring.compare.CheckEmployeeService;
import com.example.monitoring.compare.Employee;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class EmployeeServiceImpl {
public static void main(String[] args) {
Employee employee1 = new Employee(5, "Antwaun", 5.5, 10000L, 1);
Employee employee2 = new Employee(2, "Rick", 32.5, 2000L, 3);
Employee employee3 = new Employee(1, "Richard", 50, 3000L, 4);
Employee employee4 = new Employee(3, "Corey", 22.5, 20000L, 2);
Employee employee5 = new Employee(4, "Chumlee", 10.5, 15000L, 5);
List<Employee> employeeList = new ArrayList<>();
employeeList.add(employee1);
employeeList.add(employee2);
employeeList.add(employee3);
employeeList.add(employee4);
employeeList.add(employee5);
printEmployeeExpGreaterTenYears(employeeList);
printPersons(employeeList, new CheckEmployeeService());
System.out.println("Lambda expression ");
printPersons(employeeList,
(Employee employee) -> employee.getExperience() >= 10 && employee.getRating() >= 4);
printEmployeesWithPredicate(employeeList,
(Employee employee) -> employee.getExperience() >= 10 && employee.getRating() >= 4);
employeeList
.stream()
.filter(
employee -> employee.getExperience() >= 10 && employee.getRating() >= 4)
.forEach(employee -> System.out.println(employee));
}
public static void printEmployeeExpGreaterTenYears(List<Employee> employeeList){
for(Employee employee: employeeList){
if(employee.getExperience() >= 10){
System.out.println(employee);
}
}
}
public static void printEmployeeExpGreaterTenYearsAndSalaryPassed(
List<Employee> employeeList, int rating){
for(Employee employee: employeeList){
if(employee.getExperience() >= 10 && employee.getRating() >= rating){
System.out.println(employee);
}
}
}
public static void printPersons(
List<Employee> employeeList, CheckEmployee checkEmployee){
for(Employee employee: employeeList){
if(checkEmployee.test(employee)){
System.out.println(employee);
}
}
}
public static void printEmployeesWithPredicate(
List<Employee> roster, Predicate<Employee> tester) {
for (Employee p : roster) {
if (tester.test(p)) {
System.out.println(p);
}
}
}
}