La programación funcional en Java se desarrolló con la llegada de las expresiones lambda y las interfaces funcionales (a partir de Java 8).
Historia del tema
Antes de Java 8, todas las interfaces eran un conjunto de métodos abstractos y la paradigma estaba orientada a OOP. Con la introducción de interfaces funcionales y expresiones lambda, se hizo posible escribir código más compacto y seguir principios de FP, lo que mejoró la legibilidad y expresividad del código.
Problema
El código relacionado con el manejo de eventos, colecciones o lógica asíncrona se volvía redundante: era necesario crear clases separadas o clases internas anónimas. Esto dificultaba el mantenimiento y la escalabilidad del código.
Solución
Una interfaz funcional es una interfaz con exactamente un método abstracto. Se puede usar como objetivo para una expresión lambda. En la biblioteca estándar, surgieron interfaces funcionales tipo, como Function<T, R>, Predicate<T>, Supplier<T>, Consumer<T>, así como la posibilidad de crear sus propias interfaces.
Ejemplo de código:
import java.util.function.Function; public class FunctionalExample { public static void main(String[] args) { // Interfaz funcional estándar Function Function<String, Integer> stringLength = s -> s.length(); System.out.println(stringLength.apply("Java")); // Imprimirá 4 } }
Características clave:
¿Se puede declarar una interfaz funcional con varios métodos abstractos si los otros métodos tienen implementación por defecto o son estáticos?
No, una interfaz funcional puede contener solo un método abstracto. Se permite tener métodos por defecto (default) o estáticos.
¿Se puede heredar una interfaz funcional de otra interfaz con varios métodos abstractos?
No, si la interfaz resultante tiene más de un método abstracto, deja de ser funcional y no se puede usar para la sustitución de una expresión lambda.
¿En qué se diferencia la interfaz funcional de Java de las interfaces SAM en otros lenguajes, como C#?
En Java no hay una palabra clave directa para declarar interfaces SAM hasta la aparición de la anotación @FunctionalInterface. A diferencia de C#, donde delegate define claramente la firma, en Java es suficiente con un método abstracto y una anotación opcional para el compilador.
@FunctionalInterface: el compilador no muestra inmediatamente un error si la interfaz deja de ser funcional.En un gran proyecto, decidieron usar lambdas en todas partes, incluso donde las entidades representaban datos, sin conexión directa con la lógica de negocio. Como resultado, la lógica compleja era difícil de seguir, las lambdas ocultaban las intenciones del código y la depuración se volvió problemática.
Ventajas:
Desventajas:
En otro proyecto, se analizaba cuidadosamente qué interfaces eran adecuadas para FP. Utilizaban Predicate, Function y sus propias interfaces para el procesamiento de colecciones y eventos. Para entidades y almacenamiento de datos no se aplicaba FP.
Ventajas:
Desventajas: