#
Functions in Java
A Functional Interface
is an interface which contains exactly one abstract method.
It can have any number of default, static methods, but it can contain ONLY one abstract method.
Lambda expression is used to implement a functional interface abstract method.
Functional Interfaces and lambda expression are introduced in Java 8.
The "functions" are implementations of the Functions<T,R> functional interfaces.
In my example, I start from a simple Spring Boot application created using Spring initializr.
For my example I create an Employee class first:
package com.exampe.java;
public class Employee {
int id;
String name;
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
After that we can create a Function<Employee, String> implementation:
package com.exampe.java;
import java.util.function.Function;
public class Function1 implements Function<Employee, String> {
@Override
public String apply(Employee employee) {
return employee.getName();
}
}
And below we can see how the functions are used:
package com.exampe.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.function.Function;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
System.out.println("--------------------------------------------");
// Function using a normal class
Function1 f1 = new Function1();
Employee emp1 = new Employee(11, "Emily");
String str1 = f1.apply(emp1);
System.out.println("Emp name (I) = "+ str1);
// Function using lambda expression
Employee emp2 = new Employee(20, "Dan");
Function<Employee, String> f2 = (emp_2) -> {
return emp_2.getName();
};
String str2 = f2.apply(emp2);
System.out.println("Emp name (II) = "+ str2);
// Function using an inner class
Function<Employee, String> f3 = new Function<Employee, String>() {
public String apply(Employee employee) {
return employee.getName();
}
};
Employee emp3 = new Employee(30, "Helena");
String str3 = f1.apply(emp3);
System.out.println("Emp name (III) = "+ str3);
System.out.println("--------------------------------------------");
System.out.println("End of the execution");
}
}
When we run the application we can see:
--------------------------------------------
Emp name (I) = Emily
Emp name (II) = Dan
Emp name (III) = Helena
--------------------------------------------
End of the execution
Here are some remarks:
- "lambda expressions" could be used always with a functional interface;
- the functions could be implemented by an inner or a normal class.
- a BiFunction is implemented as a Function, but it accepts 2 objects as parameters in the apply() method.
There are a couple of predefined functional interfaces:
Predicate<T>orBiPredicates<T,U>: used for filters, we need to define test(T) or test(T, U) method. This method returns a boolean value.Consumer<T>orBiConsumer<T,U>: we need to define accept(T) or accept(T, U) method. This method returns no value.Supplier<T>: we need to return theobject . The get() method will be used to obtain the object returned by the supplier.Function<T, R>orBiFunction<T,U,R>: we need to define apply(T) or apply(T, U) method. This method returns an R object.UnaryOperator<T>orBinaryOperator<T,T>: we need to return a T object.
Info
T, U, R are generic types of objects.
