Lambda expressions are introduced in Java 8 and is one of the most important feature of Java 8. A Lambda expression is a block of code with can be passed around and executed which is not possible in the previous versions of Java, other programming languages such as LISP, Python, Ruby, Scala etc.. has this feature.
With the introduction of Lambda expressions Java paved way for Functional programming. In this post, let’s get the basic understanding on what is functional programming and the need for lambda expressions with examples.
What is Functional programming?
Functional programming is a paradigm which allows programming using expressions (i.e.) passing functions as arguments and using functions as statements. Lambda expression provides implementation of functional interface.
A Functional Interface is an interface which contains only one abstract method, such type of interfaces are called functional interfaces and the method of the functional interface is called as functional method or single abstract method (SAM).
Why we need Lambdas expression?
- Enables us to write Functional Programming through Functional Interface
- Improves the readability of the code and eliminates some of the boilerplate code
- Enables support for parallel processing
Syntax of Lambda Expressions
The Lambda Expression syntax looks like below
(parameter) -> {body}
- Parameter: It can be either empty or non-empty
- Arrow Operator : The arrow operator links the parameter and body
- Body: It has the statements for the lambda expressions.
Optional elements in Java Lambda Expressions
Let’s understand the optional elements with some examples.
- Brackets (): The brackets are not manadatory when there is only one parameter but for multiple parameters we need to provide the brackets.
public class LambdaExample { public static void main(String[] args) { HelloWorld mylambda1= (String s) -> {System.out.println("Hello 1 "+s);}; HelloWorld mylambda2= s -> {System.out.println("Hello 2 "+s);}; mylambda1.greet("World"); mylambda2.greet("JIP"); } } interface HelloWorld { public void greet(String welcome); }
- Parameter Type: The type of the parameter passed in an lambda expression is optional, the compiler can inference it automatically.
public class LambdaExample { public static void main(String[] args) { HelloWorld mylambda1= (String s) -> {System.out.println("Hello 1 "+s);}; HelloWorld mylambda2= (s) -> {System.out.println("Hello 2 "+s);}; mylambda1.greet("World"); mylambda2.greet("JIP"); } } interface HelloWorld { public void greet(String welcome); }
- Curly braces {}: The curly braces is not a mandatory one when the body contains a single statement, when the body has multiple statements then we need to provide the curly braces.
public class LambdaExample { public static void main(String[] args) { HelloWorld mylambda1= (String s) -> {System.out.println("Hello 1 "+s);}; HelloWorld mylambda2= (s) -> System.out.println("Hello 2 "+s); mylambda1.greet("World"); mylambda2.greet("JIP"); } } interface HelloWorld { public void greet(String welcome); }
- Return statement: Compiler will automatically returns the values the body contains a single statement. Whenever return is mentioned explicitly then we need to have the curly braces.
public class LambdaExample { public static void main(String[] args) { HelloWorld mylambda1= (String s) -> {return s;}; HelloWorld mylambda2= (String s) -> s; System.out.println( mylambda1.greet("Hello") ); System.out.println( mylambda2.greet("World") ); } } interface HelloWorld { public String greet(String welcome); }
Java 8 Lambda Expressions vs Anonymous Inner Class
A class without no name is called as an Anonymous inner class in Java, they are anonymous and inline and should override the methods of the interface. Prior to Java 8, we need to create an anonymous inner class to implement the functional interface.
In the below code we have created an anonymous inner class of the Runnable interface and overridden the run() method.
package com.javainterviewpoint; public class LambdaExample { public static void main(String[] args) { Thread t = new Thread (new Runnable(){ @Override public void run() { System.out.println("Thread created!!"); } }); t.start(); } }
Instead of creating an anonymous inner class it can be simplified using the Java lambda expression like below
public class LambdaExample { public static void main(String[] args) { Thread t = new Thread (() -> {System.out.println("Thread created!!");}); t.start(); } }
Lambda Expression Example
Example 1: Java Lambda Expressions with No Parameter
package com.javainterviewpoint; interface HelloWorld { public void greet(); } public class LambdaExample { public static void main(String[] args) { HelloWorld mylambda= () -> {System.out.println("Hello");}; mylambda.greet(); } }
Example 2: Java Lambda Expression with Single Parameter
package com.javainterviewpoint; interface HelloWorld { public void greet(String s); } public class LambdaExample { public static void main(String[] args) { HelloWorld mylambda= (String s) -> {System.out.println("Hello "+s);}; mylambda.greet("World"); } }
Example 3: Java Lambda Expression with Multiple Parameters
package com.javainterviewpoint; interface HelloWorld { public void greet(String s1, String s2); } public class LambdaExample { public static void main(String[] args) { HelloWorld mylambda= (s1,s2) -> {System.out.println("Hello "+s1+" "+s2);}; mylambda.greet("World","JIP"); } }
Example 4: Passing Java Lambda Expressions as a parameter
In the below code we have passed the lambda expression as a parameter to the welcome() method.
package com.javainterviewpoint; interface HelloWorld { public void greet(String s); } public class LambdaExample { public static void main(String[] args) { welcome((s) -> {System.out.print("Hello "+s);}); } public static void welcome(HelloWorld hello) { hello.greet("World"); } }
Example 5: Java 8 Lambda forEach – Iterating a List
forEach() is default method defined in the Iterable interface, the Collections classes which extends Iterable interface can use forEach() loop to iterate elements.
package com.javainterviewpoint; import java.util.ArrayList; import java.util.List; public class LambdaExample { public static void main(String[] args) { List<String> sportsList = new ArrayList<String>(); sportsList.add("Cricket"); sportsList.add("Football"); sportsList.add("Tennis"); sportsList.add("Hockey"); System.out.println("*** Before Java 8 ***"); //Before Java 8 for(String sport : sportsList) { System.out.println(sport); } System.out.println("*** After Java 8 ***"); //Using Lambda Expressions sportsList.forEach((sport) -> System.out.println(sport)); } }
Example 6: Java 8 Lambda forEach Lambda Java – Iterating a Map
package com.javainterviewpoint; import java.util.HashMap; import java.util.Map; public class LambdaExample { public static void main(String[] args) { Map<String, String> sportsMap = new HashMap<>(); sportsMap.put("C", "Cricket"); sportsMap.put("F", "Football"); sportsMap.put("H", "Hockey"); sportsMap.put("T", "Tennis"); System.out.println("*** Before Java 8 ***"); //Before Java 8 for(Map.Entry<String, String> entry : sportsMap.entrySet()) { System.out.println(entry.getKey()+" "+entry.getValue()); } System.out.println("*** After Java 8 ***"); //Using Lambda Expressions sportsMap.forEach((k , v) -> System.out.println(k+" "+v)); } }
Example 7: Java Comparator with Lambda Expression
The Comparator is also a Functional Interface it has one abstract method compare() and hence it can be used for Java lambda. Let’s sort the list using comparator based on firstname
package com.javainterviewpoint; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class LambdaExample { public static void main(String[] args) { List employeeList1 = new ArrayList<>(); employeeList1.add(new Employee("Charlie","Brown",10)); employeeList1.add(new Employee("Johny","Walker",33)); employeeList1.add(new Employee("Bravo","Dwayne",22)); employeeList1.add(new Employee("Fox","Lee",54)); System.out.println("*** Before Java 8 ***"); //Before Java 8 Collections.sort(employeeList1, new Comparator() { @Override public int compare(Employee e1, Employee e2) { return e1.getFirstName().compareTo(e2.getFirstName()); } }); for (Employee e : employeeList1) { System.out.println(e); } List employeeList2 = new ArrayList<>(); employeeList2.add(new Employee("Charlie","Brown",10)); employeeList2.add(new Employee("Johny","Walker",33)); employeeList2.add(new Employee("Bravo","Dwayne",22)); employeeList2.add(new Employee("Fox","Lee",54)); System.out.println("*** After Java 8 ***"); //After Java 8 Collections.sort(employeeList2, (e1,e2)-> {return e1.getFirstName().compareTo(e2.getFirstName());} ); for (Employee e : employeeList2) { System.out.println(e); } } }
Employee POJO
package com.javainterviewpoint; public class Employee { private String firstName; private String lastName; private int age; public Employee(String firstName, String lastName, int age) { super(); this.firstName = firstName; this.lastName = lastName; this.age = age; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [firstName=" + firstName + ", lastName=" + lastName + ", age=" + age + "]"; } }
Leave a Reply