Java Lambda Expressions
Introduction
?Lambda Expression was introduced in Java 8. They provide a clear and concise way to represent one method interface using an expression.
Basically it is used to create an anonymous function which can be executed on demand. It doesn't execute on its own but provides implementation of functional interface.
Advantage of Lambda Expressions are:
- Clear and Concise code
- More readability
- Facilitates functional programming
- Less boilerplate code and simplifies development work (i.e., No need to create anonymous class)
- Easy maintenance
Functional Interface
Functional Interface is an interface which has only one abstract method. Java provides an annotation @FunctionalInterface which is used to declare an interface as functional interface.
Example:
@FunctionalInterface public interface Interface { public abstract <Return-Type> methodName(parameters); }
Let's have a look into lambda syntax and examples
Syntax:
() -> expression
or
(parameters) -> expression
or
(parameters) -> { statements; }
Example:
public class LambdaExpressionExample { public static void main(String[] args) { classicWay(); lambdaWay(); } static void classicWay() { Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("Classic Way: Processing.."); } }); thread.start(); } static void lambdaWay() { Thread thread = new Thread(() -> { System.out.println("Lambda Way: Processing.."); }); thread.start(); } } Output: Classic Way: Processing.. Lambda Way: Processing..
From the above example, It is clear that we do not have to create anonymous class thus reduces the number of lines of code and increases the readability
More lambda expression examples:
() -> System.out.println("Hello World") (String name) -> { System.out.println("Hello " + name); } (name) -> { System.out.println("Hello " + name); } (double radius) -> { return 2 * 3.142 * radius; } (int m) -> { return m*m; } (n) -> n*n*n (arr) -> { int max = Integer.MIN_VALUE; for(int n: arr) { if(n > max) max = n; } return max; };
Lambda Expression with no parameter
@FunctionalInterface interface Greeting { void sayHello(); } public class Main { public static void main(String[] args) { Greeting greeting = () -> System.out.println("Hello World"); greeting.sayHello(); } } Output: Hello World
Lambda Expression with one parameter
@FunctionalInterface interface Greeting { void sayHello(String name); } public class Main { public static void main(String[] args) { Greeting greeting = (name) -> System.out.println("Hello " + name); greeting.sayHello("Ami"); } } Output: Hello Ami
Lambda Expression with two parameter
@FunctionalInterface interface Greeting { void sayHello(String firstname, String lastname); } public class Main { public static void main(String[] args) { Greeting greeting = (fn, ln) -> System.out.printf("Hello %s %s", fn, ln); greeting.sayHello("Naruto", "Uzumaki"); } } Output: Hello Naruto Uzumaki
Lambda Expression can be assigned to a variable
@FunctionalInterface interface MathInterface { int cube(int n); } public class LambdaExpressionExample { public static void main(String[] args) { MathInterface math = (n) -> n*n*n; System.out.println("6 cube is = " + math.cube(6)); } } Output: 6 cube is = 216
Lambda Expression can be passed to functions
@FunctionalInterface interface Operator { int operate(int m, int n); } enum Operation { ADD, SUB, MUL, DIV } public class LE2 { public static void main(String[] args) { Operator ADD = (m, n) -> m+n; Operator SUB = (m, n) -> m-n; Operator MUL = (m, n) -> m*n; Operator DIV = (m, n) -> m/n; calculate(ADD, Operation.ADD, 12 , 10); calculate(SUB, Operation.SUB, 15 , 7); calculate(MUL, Operation.MUL, 16, 6); calculate(DIV, Operation.DIV, 18, 5); } static void calculate(Operator counter, Operation operation, int m, int n) { int result = counter.operate(m, n); System.out.printf("%d %s %d = %d\n", m, operation.toString(), n, result); } } Output: 12 ADD 10 = 22 15 SUB 7 = 8 16 MUL 6 = 96 18 DIV 5 = 3
Lambda Expression can be returned from functions
@FunctionalInterface interface Operator { int operate(int m, int n); } enum Operation { ADD, SUB, MUL, DIV } public class LambdaExpressionExample { public static void main(String[] args) { calculate(12, 5, Operation.ADD); calculate(15, 7, Operation.SUB); calculate(16, 6, Operation.MUL); calculate(18, 5, Operation.DIV); } static void calculate(int m, int n, Operation operation) { Operator operator = getOperator(operation); int result = operator.operate(m, n); System.out.printf("%d %s %d = %d \n", m, operation.toString(), n, result); } static Operator getOperator(Operation operation) { switch (operation) { case ADD: return (m, n) -> m + n; case SUB: return (m, n) -> m - n; case MUL: return (m, n) -> m * n; case DIV: return (m, n) -> m / n; default: throw new IllegalArgumentException("Invalid operation"); } } } Output: 12 ADD 5 = 17 15 SUB 7 = 8 16 MUL 6 = 96 18 DIV 5 = 3
Lambda Expressions and Generic Functional Interface
@FunctionalInterface interface GenericInterface<T> { T func(T t); } public class LambdaExpressionExample { public static void main(String[] args) { // Accepts Integer type parameter GenericInterface<Integer> square = (n) -> n * n; System.out.println("Square of n = " + square.func(12)); // Accepts String type parameter GenericInterface<String> repeat = (s) -> s.repeat(3); System.out.println("Repeat string 3 times = " + repeat.func("COOL")); // Accepts Double type parameter GenericInterface<Double> degreeToRadian = (v) -> Math.toRadians(v); System.out.println("120.8 deg in radians = " + degreeToRadian.func(120.8)); } } Output: Square of 12 = 144 Repeat string 3 times = COOLCOOLCOOL 120.8 deg in radians = 2.10835773640915
Lambda Expressions and Stream API
Example-1
public class LambdaWay { public static void main(String[] args) { int[] results = {12, 28, 19, 81, 43, 62, 97, 6, 35, 56}; Arrays.stream(results) .filter(result -> result >= 35) .forEach(result -> System.out.print(result + "\t")); } } Output: 81 43 62 97 35 56
Example-2
public class LambdaWithStream { public static void main(String[] args) { List<User> users = List.of(new User("Naruto", 246), new User("Ami", 523), new User("Luffy", 289), new User("Shanks", 455), new User("Zoro", 182), new User("Yagami Light", 721)); System.out.println("Users with more than 250 reward points"); System.out.println("Name\t\tReward points"); users.stream() .filter(user -> user.points > 250) .forEach(user -> System.out.printf("%-15s %d\n", user.name, user.points)); } static class User { String name; int points; User(String name, int points) { this.name = name; this.points = points; } } } Output: Users with more than 250 reward points Name Reward points Ami 523 Luffy 289 Shanks 455 Yagami Light 721
?References
More Links
Thanks for reading. Please like & share the article.