Lambda Expression
- 4th Sep 2014
- 0
- 14229
- Arithmetic Operation with lambda expression How to use Comparator on lambda expression with an example How to use lambda expression for collection iteration with an example How to use lambda expression with an example lambda expression in java with an example significance of lambda expresion when to use lambda expression
It is a shorter way of writing an implementation of a method which we can execute later at some point.
Syntax :
- (arg1,arg2,arg3,…) -> {body of implementing method};
(arg1,arg2,arg3,…) -> {body of implementing method};
Example 1 :
- (int x, int y,int z) -> { return x + y + z; };
(int x, int y,int z) -> { return x + y + z; };
Example 2 :
- () -> System.out.println("no arg method");
() -> System.out.println("no arg method");
Example 3 :
- (String s) -> { System.out.println(s); };
(String s) -> { System.out.println(s); };
Example 4 :
- () -> 10
() -> 10
Example 5 :
- () -> { return 3.14 };
() -> { return 3.14 };
Note :
Lambda can be used only for functional interfaces Even if there is an abstract class with one and only one abstract method also Lambda will not work.
Consider an abstract class as below
- package com.kb.Lambda;
- public abstract class AbstractClass {
- abstract void show();
- }
package com.kb.Lambda; public abstract class AbstractClass { abstract void show(); }
Create an implementor
- package com.kb.Lambda;
- public class AbstractClassImplementor {
- public static void main(String[] args) {
- AbstractClass abstractClass = new AbstractClass() {
- @Override
- void show() {
- System.out.println("show called");
- }
- };
- //New way using lambda
- AbstractClass abstractClass1 = () -> System.out.println("show called new way");
- }
- }
package com.kb.Lambda; public class AbstractClassImplementor { public static void main(String[] args) { AbstractClass abstractClass = new AbstractClass() { @Override void show() { System.out.println("show called"); } }; //New way using lambda AbstractClass abstractClass1 = () -> System.out.println("show called new way"); } }
No doubt this new way will give the compile time error.
So lambda expression can not be used with abstract class even if it is containing single abstarct method.
So it must be used only in case of functional interface.
Key points on Lambda expression are
1) A lambda expression can have zero, one or more parameters which is decided as per the method signature in functional interface.
2) The type of the parameters can be explicitly declared or it can be inferred from the context.
Example : (int a,int b) is same as just (a,b)
3) Empty parentheses should be used to represent an empty set of parameters.
Example : ( ) -> 1
4) If method in functional interface has single parameter, and it’s type is inferred, it is not mandatory to use parentheses.
Example : a -> return a+a;
5) If body of lambda expression has single statement, curly brackets are not mandatory and the return type of the anonymous function is the same as that of the body expression.
6) When there is more than one statement in body than these must be enclosed in curly brackets and the return type of the anonymous function is the same as the type of the value returned within the block, or void if nothing is returned.
Below are few examples on how to use lambda expression
Using lambda expression
- package com.kb.Lambda;
- public class LambdaEx1 {
- public static void main(String[] args) {
- Runnable r = new Runnable() {
- @Override
- public void run() {
- System.out.println("old way of calling run method");
- }
- };
- r.run();
- Runnable newR = () -> System.out.println("new way of calling run method using Lambda");
- newR.run();
- }
- }
package com.kb.Lambda; public class LambdaEx1 { public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { System.out.println("old way of calling run method"); } }; r.run(); Runnable newR = () -> System.out.println("new way of calling run method using Lambda"); newR.run(); } }
- new Thread(
- () -> System.out.println("run method")
- ).start();
new Thread( () -> System.out.println("run method") ).start();
So in above code, compiler automatically detects that lambda expression can be casted to Runnable interface from Thread class’s constructor signature
- public Thread(Runnable r) {
- }
public Thread(Runnable r) { }
Functional interface with lambda on method call
- package com.kb.Lambda;
- @FunctionalInterface
- interface FunctionalInterfaceExample1{
- void show();
- }
- public class FunctionalInterfaceAndLambda {
- static void executeFunctionalInterface(FunctionalInterfaceExample1 example1){
- example1.show();
- }
- public static void main(String[] args) {
- //old way1
- executeFunctionalInterface(new FunctionalInterfaceExample1() {
- @Override
- public void show() {
- System.out.println("old way of defining anonymous inner class");
- }
- });
- // old way2
- FunctionalInterfaceExample1 ex1 = new FunctionalInterfaceExample1() {
- @Override
- public void show() {
- System.out.println("still old way of defining anonymous inner class");
- }
- };
- executeFunctionalInterface(ex1);
- //new way using lambda
- executeFunctionalInterface(() -> {System.out.println("new way of defining anonymous inner class using lambda");});
- }
- }
package com.kb.Lambda; @FunctionalInterface interface FunctionalInterfaceExample1{ void show(); } public class FunctionalInterfaceAndLambda { static void executeFunctionalInterface(FunctionalInterfaceExample1 example1){ example1.show(); } public static void main(String[] args) { //old way1 executeFunctionalInterface(new FunctionalInterfaceExample1() { @Override public void show() { System.out.println("old way of defining anonymous inner class"); } }); // old way2 FunctionalInterfaceExample1 ex1 = new FunctionalInterfaceExample1() { @Override public void show() { System.out.println("still old way of defining anonymous inner class"); } }; executeFunctionalInterface(ex1); //new way using lambda executeFunctionalInterface(() -> {System.out.println("new way of defining anonymous inner class using lambda");}); } }
Collection iteration with lambda expression
forEach method is added to List interface in Java8 and it can be used as below with lambda.
Create IteratingList.java
- package com.kb.Lambda;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.function.Consumer;
- public class IteratingList {
- public static void main(String[] args) {
- List<Integer> list = new ArrayList<Integer>();
- list.add(10);
- list.add(20);
- //old way of iterating
- for (Integer element : list) {
- System.out.println(element);
- }
- System.out.println("-----------------");
- //new way using lambda
- list.forEach(element -> {System.out.println(element);});
- }
- }
package com.kb.Lambda; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; public class IteratingList { public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); list.add(10); list.add(20); //old way of iterating for (Integer element : list) { System.out.println(element); } System.out.println("-----------------"); //new way using lambda list.forEach(element -> {System.out.println(element);}); } }
Arithmetic Operation with lambda expression
Create Calculator.java
- package com.kb.Lambda;
- public class Calculator {
- interface IntegerMath {
- int operation(int a, int b);
- }
- public int operateBinary(int a, int b, IntegerMath operation) {
- return operation.operation(a, b);
- }
- public static void main(String... args) {
- Calculator myApp = new Calculator();
- IntegerMath addition = (a, b) -> a + b;
- IntegerMath subtraction = (a, b) -> a - b;
- System.out.println("40 + 2 = " +
- myApp.operateBinary(40, 2, addition));
- System.out.println("20 - 10 = " +
- myApp.operateBinary(20, 10, subtraction));
- }
- }
package com.kb.Lambda; public class Calculator { interface IntegerMath { int operation(int a, int b); } public int operateBinary(int a, int b, IntegerMath operation) { return operation.operation(a, b); } public static void main(String... args) { Calculator myApp = new Calculator(); IntegerMath addition = (a, b) -> a + b; IntegerMath subtraction = (a, b) -> a - b; System.out.println("40 + 2 = " + myApp.operateBinary(40, 2, addition)); System.out.println("20 - 10 = " + myApp.operateBinary(20, 10, subtraction)); } }
Comparator with lambda expression
Create a class person
- package com.kb.Lambda;
- public class Person {
- String name;
- String designation;
- int age;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getDesignation() {
- return designation;
- }
- public void setDesignation(String designation) {
- this.designation = designation;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- @Override
- public String toString() {
- return "name is "+name+" age is "+age+" designation is "+designation;
- }
- }
package com.kb.Lambda; public class Person { String name; String designation; int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDesignation() { return designation; } public void setDesignation(String designation) { this.designation = designation; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "name is "+name+" age is "+age+" designation is "+designation; } }
Create a client class which uses person
- package com.kb.Lambda;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.List;
- public class PersonUser {
- public static void main(String[] args) {
- Person p1 = new Person();
- p1.setName("kb");
- p1.setDesignation("se");
- p1.setAge(26);
- Person p2 = new Person();
- p2.setName("hani");
- p2.setDesignation("se");
- p2.setAge(28);
- List<Person> people = new ArrayList<Person>();
- people.add(p1);
- people.add(p2);
- System.out.println("people before sorting");
- System.out.println(people);
- //Collections.sort(people,new PersonComparator());
- Collections.sort(people,new Comparator<Person>() {
- @Override
- public int compare(Person p1, Person p2) {
- return p1.getName().compareTo(p2.getName()) ;
- }
- });
- System.out.println("people after sorting");
- System.out.println(people);
- }
- }
package com.kb.Lambda; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class PersonUser { public static void main(String[] args) { Person p1 = new Person(); p1.setName("kb"); p1.setDesignation("se"); p1.setAge(26); Person p2 = new Person(); p2.setName("hani"); p2.setDesignation("se"); p2.setAge(28); List<Person> people = new ArrayList<Person>(); people.add(p1); people.add(p2); System.out.println("people before sorting"); System.out.println(people); //Collections.sort(people,new PersonComparator()); Collections.sort(people,new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.getName().compareTo(p2.getName()) ; } }); System.out.println("people after sorting"); System.out.println(people); } }
In the above code Collections.sort( ) method takes comparator type as a parameter and provides implementation to the compareTo() method
Now above Collections.sort( ) method can be replaced using lambda expression as below
- Collections.sort(people, (a,b) ->{ return a.getName().compareTo(b.getName());});
Collections.sort(people, (a,b) ->{ return a.getName().compareTo(b.getName());});