Java 8 Functional Interfaces
Java 8 introduced the concept of functional interfaces, which are interfaces that contain exactly one abstract method. These interfaces are also known as Single Abstract Method (SAM) interfaces or functional interfaces. The functional interfaces in Java 8 enable the use of lambda expressions and method references, promoting functional programming paradigms. Here are three examples of functional interfaces in Java 8:
Predicate<T>
Description: Represents a predicate (boolean-valued function) that takes an argument of type T and returns a boolean result.
Predicate<Integer> isGreaterThanTen = (num) -> num > 10;
boolean result = isGreaterThanTen.test(15); // true
Consumer<T>
Description: Represents an operation that takes an argument of type T and returns no result.
Consumer<String> printElement = (element) -> System.out.println(element);
List<String> list = Arrays.asList("Apple", "Banana", "Orange");
list.forEach(printElement);
Function<T, R>
Description: Represents a function that takes an argument of type T and produces a result of type R.
Function<String, String> toUpperCase = (str) -> str.toUpperCase();
String result = toUpperCase.apply("hello"); // "HELLO"
Java Functional Programming with Lambda Expressions
Example 1: Addition
Functional Interface: BinaryOperator<Integer>
BinaryOperator<Integer> add = (a, b) -> a + b;
int result = add.apply(5, 3); // 8
Example 2: Filtering
Functional Interface: Predicate<String>
List<String> fruits = Arrays.asList("Apple", "Banana", "Orange");
Predicate<String> startsWithA = (str) -> str.startsWith("A");
List<String> filteredFruits = fruits.stream()
.filter(startsWithA)
.collect(Collectors.toList());
// filteredFruits: ["Apple"]
Example 3: Mapping
Functional Interface: Function<String, Integer>
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Function<String, Integer> nameLength = (str) -> str.length();
List<Integer> nameLengths = names.stream()
.map(nameLength)
.collect(Collectors.toList());
// nameLengths: [5, 3, 7]
Example 4: Reducing
Functional Interface: BinaryOperator<Integer>
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
BinaryOperator<Integer> sum = (a, b) -> a + b;
int total = numbers.stream()
.reduce(0, sum);
// total: 15
Functional Interfaces vs. Anonymous Inner Classes in Java
Functional Interfaces
In Java, a functional interface is an interface that has only one abstract method. It can be used as the basis for lambda expressions or method references, enabling functional programming in Java.
Example:
@FunctionalInterface
interface MyFunction {
void doSomething();
}
// Using a lambda expression
MyFunction lambda = () -> System.out.println("Using lambda expression");
lambda.doSomething();
// Using a method reference
MyFunction methodRef = MyClass::doSomething;
methodRef.doSomething();
Anonymous Inner Classes
In Java, an anonymous inner class is a class without a name that is defined and instantiated at the same time. It is often used when implementing interfaces or extending classes.
Example:
interface MyInterface {
void doSomething();
}
// Using an anonymous inner class
MyInterface anonymousInnerClass = new MyInterface() {
public void doSomething() {
System.out.println("Using anonymous inner class");
}
};
anonymousInnerClass.doSomething();
Differences
- Functional interfaces provide a concise way to define single abstract method interfaces using lambda expressions or method references.
- Anonymous inner classes are used when more flexibility is needed, allowing the implementation of multiple methods and access to local variables.
- Functional interfaces are preferred for simple functional programming scenarios, while anonymous inner classes provide more flexibility but with more verbose syntax.