Functional Interfaces in Java 8
Overview
Functional interfaces are a new feature introduced in Java 8. They are interfaces that have a single abstract method, and can thus be implemented using lambda expressions, method references, or anonymous classes. This makes them a key component of the functional programming paradigm in Java.
Definition
A functional interface is defined with the help of the @FunctionalInterface
annotation, although this annotation is optional. The presence of a single abstract method is what makes an interface functional.
Example: Defining a Functional Interface
@FunctionalInterface interface MyFunctionalInterface { void myMethod(); }
Built-in Functional Interfaces
Java 8 provides several built-in functional interfaces in the java.util.function
package. Some of the most commonly used ones are:
Predicate<T>
: Represents a predicate (boolean-valued function) of one argument.Function<T, R>
: Represents a function that accepts one argument and produces a result.Supplier<T>
: Represents a supplier of results.Consumer<T>
: Represents an operation that accepts a single input argument and returns no result.UnaryOperator<T>
: Represents an operation on a single operand that produces a result of the same type as its operand.BinaryOperator<T>
: Represents an operation upon two operands of the same type, producing a result of the same type as the operands.
Example: Using a Built-in Functional Interface
Using Predicate
to filter a list of strings:
import java.util.Arrays; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; public class PredicateExample { public static void main(String[] args) { Listnames = Arrays.asList("Alice", "Bob", "Charlie", "David"); Predicate startsWithA = name -> name.startsWith("A"); List namesStartingWithA = names.stream() .filter(startsWithA) .collect(Collectors.toList()); System.out.println(namesStartingWithA); } }
Lambda Expressions with Functional Interfaces
Lambda expressions are a natural fit for functional interfaces. They allow you to provide the implementation of the abstract method defined by the functional interface.
Example: Implementing a Functional Interface using a Lambda Expression
@FunctionalInterface interface MyFunctionalInterface { void myMethod(); } public class LambdaExample { public static void main(String[] args) { MyFunctionalInterface myFunc = () -> System.out.println("Hello, World!"); myFunc.myMethod(); } }
Method References with Functional Interfaces
Method references can also be used to provide implementations for functional interfaces, making the code even more concise and readable.
Example: Implementing a Functional Interface using a Method Reference
import java.util.function.Consumer; public class MethodReferenceExample { public static void main(String[] args) { Consumerprinter = System.out::println; printer.accept("Hello, Method Reference!"); } }
Custom Functional Interfaces
In addition to the built-in functional interfaces, you can create your own custom functional interfaces to meet specific needs in your application.
Example: Creating and Using a Custom Functional Interface
@FunctionalInterface interface Calculator { int calculate(int a, int b); } public class CustomFunctionalInterfaceExample { public static void main(String[] args) { Calculator add = (a, b) -> a + b; Calculator subtract = (a, b) -> a - b; System.out.println("Addition: " + add.calculate(5, 3)); System.out.println("Subtraction: " + subtract.calculate(5, 3)); } }
Conclusion
Functional interfaces in Java 8 are a powerful feature that enable functional programming paradigms. By using built-in and custom functional interfaces along with lambda expressions and method references, you can write more concise and readable code.