Functional Interface in Java 8 | Code Examples Explained
What is Functional Interface in Java?
A functional interface in Java is an interface with a single abstract method. This allows it to be used as the target type for a lambda expression or method reference. It is also known as SAM (Single Abstract Method) interface. It can have any number of default and static methods but a single abstract method.
Java uses @FunctionalInterface
annotation to mark an interface as functional although it is optional but is better to follow the standard for good coding practice.
By using functional interfaces and lambda expressions, we can write more concise and readable code. It also enables us to pass behavior as a method argument, making our code more flexible and modular.
For example, consider a class that sorts a list of Person
objects. Without using functional interfaces and lambda expressions, we would need to create a separate Comparator
class for each sort order.
Example: Compare Objects without using Functional Interface
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Person { private String firstName; private String lastName; private int 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; } public Person(String firstName, String lastName, int age) { super(); this.firstName = firstName; this.lastName = lastName; this.age = age; } public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("John", "Doe", 30)); people.add(new Person("Jane", "Doe", 25)); people.add(new Person("Jim", "Smith", 35)); Collections.sort(people, new AgeComparator()); System.out.println(people); } } class AgeComparator implements java.util.Comparator<Person> { @Override public int compare(Person a, Person b) { return a.getAge() - b.getAge(); } }
With functional interfaces and lambda expressions, we can simplify the code by passing the sort order as a lambda expression directly to the sort method.
Example: Compare Objects by using Functional Interface
mport java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class Person { private String firstName; private String lastName; private int 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; } public Person(String firstName, String lastName, int age) { super(); this.firstName = firstName; this.lastName = lastName; this.age = age; } public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("John", "Doe", 30)); people.add(new Person("Jane", "Doe", 25)); people.add(new Person("Jim", "Smith", 35)); Collections.sort(people, (a, b) -> a.getAge() - b.getAge()); System.out.println(people); } }
In this example, the lambda expression (a, b) -> a.getAge() - b.getAge()
implements the compare method of the Comparator interface, and can be used to sort a list of Person objects by age.
Built-in Functional Interface in Java 8
Java 8 provides several built-in functional interfaces some of which are listed below.
- java.lang.Runnable
- java.util.Comparator
- java.util.function.Function
- java.util.function.Consumer
- java.util.function.Predicate
Java Consumer Interface
For example, the java.util.function.Consumer
functional interface defines a single abstract method accept which takes an object and returns no result.
It can be used to represent an operation that takes an object and performs some action on it, such as printing the object to the console.
mport java.util.function.Consumer; public class Main { public static void main(String[] args) { Consumer<String> consumer = s -> System.out.println(s); consumer.accept("Hello World"); } }
Output:
Hello World
Java Predicate Interface
Another example is the java.util.function.Predicate
functional interface which defines a single abstract method test that takes an object and returns a boolean. It can be used to represent a condition or a test that takes an object and returns a true or false result.
import java.util.function.Predicate; public class Main { public static void main(String[] args) { Predicate<String> predicate = s -> s.length() > 5; System.out.println(predicate.test("Hello")); System.out.println(predicate.test("World")); } }
In this example, the lambda expression s -> s.length() > 5
implements the test method of the Predicate interface, and can be used to test whether a String has a length greater than 5.
Conclusion
The functional interface is a new feature introduced in Java 8 with to support functional programming. You can implement its abstract method as a lambda expression which is again good for writing functional code.