Lambdas
What we’ll cover
What are they?
When to use
Syntax: Runnable, Consumer, Biconsumer, Supplier, Function, Bifunction
What is it?
- Lambda expressions are used to perform computation based on function abstraction and application.
- Lambda expressions denote method-invokation deferral.
What is the purpose?
- Lambda expression can be passed as a parameter in a method.
- We treat code in Lambda expressions as data.
- This piece of code can be passed to other objects and methods.
When is this used?
- A method reference or lambda expression can be used to abstract any logic with dynamic functionalities rather than values.
- Any implementation of Strategy Design Pattern can (and probably should) adopt lambda expressions or method references.
What is a FunctionalInterface
?
- A functional interface is an interface that contains only one abstract method.
- Lambda expressions can be used to represent the instance of a functional interface.
- The
@FunctionalInterface
annotation explicitly denotes that- this interface can only declare a single method-signature
- this interface can be expressed as a lambda.
Syntax
Types of Functional Interfaces
Name |
Has First Argument |
Has Second Argument | Has Return-Type |
---|---|---|---|
Runnable |
no |
no | no |
Consumer |
yes |
no |
no |
BiConsumer |
yes |
yes |
no |
Supplier | no | no | yes |
Function | yes | no | yes |
BiFunction | yes | yes | yes |
Runnable
- Takes no arguments
- Return nothing
- An expression which performs a mutation and returns nothing
Runnable Syntax
(Lambda)
public class MyClass {
public static void main(String[] args) {
Runnable r = () -> System.out.println("Hello world");
r.run(); // invoke the method
}
}
Runnable Syntax
(Static Method Reference)
public class MyClass {
public static void main(String[] args) {
Runnable r = MyClass::myMethod;
r.run();
}
public static void myMethod() {
System.out.println("Hello world");
}
}
Runnable Syntax
(Non-Static Method Reference)
public class MyClass {
public static void main(String[] args) {
MyClass obj = new MyClass();
Runnable r = obj::myMethod;
r.run();
}
public void myMethod() {
System.out.println("Hello world");
}
}
Consumer
- An expression which can
.accept
a single argument and returns nothing
Consumer Syntax
(Lambda)
public class MyClass {
public static void main(String[] args) {
Consumer<String> consumer = (str) -> System.out.println(str);
consumer.accept("Hello world"); // invoke the method
}
}
Consumer Syntax
(Static Method Reference)
public class MyClass {
public static void main(String[] args) {
Consumer<String> consumer = MyClass::myMethod;
consumer.accept("Hello world");
}
public static void myMethod(String str) {
System.out.println(str);
}
}
Consumer Syntax
(Non-Static Method Reference)
public class MyClass {
public static void main(String[] args) {
MyClass obj = new MyClass();
Consumer consumer = obj::myMethod;
consumer.accept("Hello world");
}
public void myMethod(String str) {
System.out.println(str);
}
}
BiConsumer
- An expression which can
.accept
two arguments and returns nothing
BiConsumer Syntax
(Lambda)
public class MyClass {
public static void main(String[] args) {
BiConsumer<String, Integer> bc;
bc = (str, num) -> System.out.println(str + " " + num);
bc.accept("Hello ", 0);
}
}
BiConsumer Syntax
(Static Method Reference)
public class MyClass {
public static void main(String[] args) {
BiConsumer<String, Integer> bc = MyClass::myMethod;
bc.accept("Hello", Integer.MAX_VALUE);
}
public static void myMethod(String str, Integer num) {
System.out.println(str + " " + num);
}
}
BiConsumer Syntax
(Non-Static Method Reference)
public class MyClass {
public static void main(String[] args) {
MyClass obj = new MyClass();
BiConsumer<String, Integer> bc = obj::myMethod;
bc.accept("Hello", Integer.MIN_VALUE);
}
public void myMethod(String str, Integer num) {
System.out.println(str + " " + num);
}
}
Supplier
- An expression which takes no arguments and returns a value
- Can
.get
reference to the value
Supplier Syntax
(Lambda)
public class MyClass {
public static void main(String[] args) {
Supplier<String> supplier = () -> "Hello world";
String result = supplier.get();
System.out.println(result);
}
}
Supplier Syntax
(Static Method Reference)
public class MyClass {
public static void main(String[] args) {
Supplier<String> supplier = MyClass::myMethod;
String result = supplier.get();
System.out.println(result);
}
public static String myMethod() {
return "Hello world";
}
}
Supplier Syntax
(Non-Static Method Reference)
public class MyClass {
public static void main(String[] args) {
MyClass obj = new MyClass();
Supplier<String> supplier = obj::myMethod;
String result = supplier.get();
System.out.println(result);
}
public void myMethod() {
return "Hello world";
}
}
Function
- An expression which takes a single argument and returns a value
- Can
.apply
an argument to compute and return a value. Predicate
is a specializedFunction
which always returns aBoolean
value.
Function Syntax
(Lambda)
public class MyClass {
public static void main(String[] args) {
Function<Date, String> function;
function = (dateObject) -> String.valueOf(dateObject);
String result = function.apply(new Date());
System.out.println(result);
}
}
Function Syntax
(Static Method Reference)
public class MyClass {
public static void main(String[] args) {
Function<Date, String> function = MyClass::myMethod;
String result = function.apply(new Date());
System.out.println(result);
}
public static String myMethod(Date date) {
return String.valueOf(date);
}
}
Function Syntax
(Non-Static Method Reference)
public class MyClass {
public static void main(String[] args) {
MyClass obj = new MyClass();
Function<Date, String> function = obj::myMethod;
String result = function.apply(new Date());
System.out.println(result);
}
public void myMethod(Date date) {
return String.valueOf(date);
}
}
BiFunction
- An expression which takes a two arguments and returns a value
- Can
.apply
two arguments to compute and return a value.
BiFunction Syntax
(Lambda)
public class MyClass {
public static void main(String[] args) {
BiFunction<Date, Long, String> function;
function = (date, num) -> String.valueOf(date.getTime() + num);
String result = function.apply(new Date(), 15L);
System.out.println(result);
}
}
BiFunction Syntax
(Static Method Reference)
public class MyClass {
public static void main(String[] args) {
BiFunction<Date, Long, String> function = MyClass::myMethod;
String result = function.apply(new Date(), 180L);
System.out.println(result);
}
public static String myMethod(Date dateObj, Long longObj) {
return String.valueOf(dateObj + longObj);
}
}
BiFunction Syntax
(Non-Static Method Reference)
public class MyClass {
public static void main(String[] args) {
MyClass obj = new MyClass();
BiFunction<Date, Long, String> function = obj::myMethod;
String result = function.apply(new Date(), 972L);
System.out.println(result);
}
public void myMethod(Date dateObj, Long longObj) {
return String.valueOf(dateObj + longObj);
}
}