Lambda expression is the one of major change in Java 8.0 after Generics, Annotations in Java 5.0. Lambda expressions are anonymous method similar to anonymous classes in Java. One of great feature Java 8.0 is Lambda expression. JavaScript already has this functionality to create anonymous functions. Lambda expression allows us to create an anonymous methods in Java as well. Lets understand what is Lambda expression in Javajava
For example (int x, int y) -> { return x * y; } is a Java Lambda expression which takes two parameters and return the multiplication of these two numbers. This expression does not have access modifier (private/protected/public or default), return type and its name. same expression can be written in JavaScript like (function (x, y) { return x * y; } ) The syntax to write Lambda expression is as (arg1, arg2, ...) -> { body of expression}. Optionally the type of argument also can be specified. e.g. (int x, int y) -> { return x * y; }express
Before moving further first let us understand Functional Interface. Java already has a Marker Interface which is an interface without any method in it. Similar to marker interface, Functional Interface can have only one abstract method. some of examples are Comparable which has exactly one method compareTo, Runnable which has only one method run. Java 8.0 introduced an annotation @FunctionalInterface which can be used to indicate an interface is Functional Interface.app
We will create a simple test class to understand Lambda expression. Suppose we want to sort a list of Students List<Student> by rollNumberide
Student.java package com.groupkt.lambda;ui
public class Student { private Integer rollNumber; private String name; private Integer age;this
/** * @param rollNumber * @param name * @param age */ public Student(Integer rollNumber, String name, Integer age) { super(); this.rollNumber = rollNumber; this.name = name; this.age = age; } /** * @return the rollNumber */ public Integer getRollNumber() { return rollNumber; } /** * @param rollNumber the rollNumber to set */ public void setRollNumber(Integer rollNumber) { this.rollNumber = rollNumber; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the age */ public Integer getAge() { return age; } /** * @param age the age to set */ public void setAge(Integer age) { this.age = age; } @Override public String toString() { return new StringBuilder() .append("{rollNumber:").append(rollNumber) .append(",name:").append(name) .append(",age:").append(age) .append("}\n") .toString(); }
} There are different ways to implement this requirement Solution 1: By Creating a class which implements Comparablecode
/**ip
/**ci
Test.java package com.groupkt.lambda;rem
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List;
public class Test {
public static void main(String[] args) { List students = new ArrayList<Student>(); // create a list of students students.add(new Student(2, "Amit", 16)); students.add(new Student(4, "Kumar", 15)); students.add(new Student(3, "Durgesh", 17)); students.add(new Student(1, "Rajendra", 14)); // call method to sort the list sort(students); System.out.println(students); } /** * comparator to sort by Students list by roll number */ private static class StudentRollNumberComparator implements Comparator<Student> { @Override public int compare(Student student1, Student student2) { return student1.getRollNumber().compareTo(student2.getRollNumber()); } } /** * sort the list of students by using the Implementing class of * Comparable interface * @param students : list of student to be sorted */ private static void sort(List<Student> students) { Collections.sort(students, new StudentRollNumberComparator()); }
} This approach will solve our purpose. Here we created a class which implements Comparator. Now let us try another approach to implement the requirement.
Solution 2: By using a anonymous class which implements Comparable
the method test can be replaced by the code as below, here we are not creating a class but directly creating an anonymous class. /**
Solution 3: By using a Lambda expression
Lambda expression can be used with any functional interface and Comparator is a functional interface, so this test method can be replaced with lambda expression as below private static void sort(List<Student> students) { Comparator<Student> rollNumberComparator = (student1, student2) -> student1.getRollNumber().compareTo(student2.getRollNumber());
Collections.sort(students,rollNumberComparator);
} Here we have a lambda expression (student1, student2) -> student1.getRollNumber().compareTo(student2.getRollNumber()); which takes two student objects to compare the rollNumbers. In this expression we not specifying the type of student1 and student2 because compiler can determine the parameter types by the Comparator<Student>. In this Lambda expression
All of thee solutions will give same result [{rollNumber:1,name:Rajendra,age:14} , {rollNumber:2,name:Amit,age:16} , {rollNumber:3,name:Durgesh,age:17} , {rollNumber:4,name:Kumar,age:15} ] Solution 4: By using method reference studentList.sort(Comparator.comparing(Student::getRollNumber));