· Miler Roque · Java · 4 min lectura
Java, ¿Qué son las interfaces funcionales?
Una interfaz funcional en Java tiene un solo método abstracto y se usa frecuentemente con lambdas para representar una operación con una sola entrada y salida.
Una interfaz funcional es un tipo especial de interfaz en Java que sólo tiene un método abstracto. Las interfaces funcionales se usan a menudo con lambdas, que son expresiones de código que se pueden tratar como valores. Las interfaces funcionales se pueden utilizar para representar una operación única con una sola entrada y una sola salida.
Por ejemplo, la interfaz java.util.function.Function<T,R>
es una interfaz funcional que toma un argumento de tipo T y devuelve un resultado de tipo R. Se puede utilizar para representar una función matemática que toma un número como entrada y devuelve otro número como resultado.
Para implementar una interfaz funcional, puede utilizar una clase anónima o una expresión lambda. Aquí hay un ejemplo de cómo se puede utilizar una expresión lambda para implementar la interfaz Function<T,R>
:
Function<Integer, String> intToString = (i) -> Integer.toString(i);
String result = intToString.apply(123);
En este ejemplo, la expresión lambda (i) -> Integer.toString(i) se utiliza para implementar el método abstracto apply de la interfaz Function<T,R>
. La expresión lambda toma un argumento i de tipo Integer y devuelve un resultado de tipo String.
1. Interfaces funcionales típicas de java
Java proporciona varias interfaces funcionales comunes en el paquete java.util.function
. Aquí hay algunas de las interfaces funcionales más comunes:
1.1 Consumer
java.util.function.Consumer<T>
: representa una operación que acepta un argumento de tipo T
y no devuelve ningún resultado.
import java.util.function.Consumer;
// Este es un ejemplo de cómo se puede utilizar un Consumer para imprimir los elementos de una lista:
List<String> list = Arrays.asList("a", "b", "c");
Consumer<String> printer = System.out::println;
list.forEach(printer);
// Esto imprimirá los elementos de la lista en una nueva línea cada uno:
// a
// b
// c
1.2 Supplier
java.util.function.Supplier<T>
: representa una operación que no acepta argumentos y devuelve un resultado de tipo T
.
import java.util.function.Supplier;
// Este es un ejemplo de cómo se puede utilizar un Supplier para generar números aleatorios:
Supplier<Double> randomNumberGenerator = Math::random;
double randomNumber = randomNumberGenerator.get();
1.3 Function
java.util.function.Function<T,R>
: representa una operación que acepta un argumento de tipo T
y devuelve un resultado de tipo R
.
import java.util.function.Function;
// Este es un ejemplo de cómo se puede utilizar un Function para convertir números enteros a cadenas:
Function<Integer, String> intToString = Object::toString;
String string = intToString.apply(123); // string es "123"
1.4 Function
java.util.function.Function<T,R>
: representa una operación que acepta un argumento de tipo T
y devuelve un resultado de tipo R
.
import java.util.function.Function;
// Este es un ejemplo de cómo se puede utilizar un Function para convertir números enteros a cadenas:
Function<Integer, String> intToString = Object::toString;
String string = intToString.apply(123); // string es "123"
1.5 Predicate
java.util.function.Predicate<T>
: representa una operación que acepta un argumento de tipo T
y devuelve un valor boolean
.
import java.util.function.Predicate;
// Este es un ejemplo de cómo se puede utilizar un Predicate para filtrar números pares de una lista:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Predicate<Integer> isEven = i -> i % 2 == 0;
list.stream().filter(isEven).forEach(System.out::println);
// Esto imprimirá los números pares de la lista en una nueva línea cada uno:
// 2
// 4
1.6 BiFunction
java.util.function.BiFunction<T,U,R>
: representa una operación que acepta dos argumentos de tipo T
y U
y devuelve un resultado de tipo R
.
import java.util.function.BiFunction;
// Este es un ejemplo de cómo se puede utilizar un BiFunction para calcular el área de un rectángulo dado su ancho y alto:
BiFunction<Double, Double, Double> rectangleArea = (width, height) -> width * height;
double area = rectangleArea.apply(10.0, 20.0); // area es 200.0
1.7 BiConsumer
java.util.function.BiConsumer<T,U>
: representa una operación que acepta dos argumentos de tipo T
, U
y no devuelve ningún resultado.
import java.util.function.BiConsumer;
// Este es un ejemplo de cómo se puede utilizar un BiConsumer para imprimir el valor máximo y mínimo de una lista de números:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
BiConsumer<Integer, Integer> printer = (min, max) -> System.out.printf("Mínimo: %d, Máximo: %d%n", min, max);
printer.accept(Collections.min(list), Collections.max(list));
// Esto imprimirá el valor mínimo y máximo de la lista:
// Mínimo: 1, Máximo: 5