Programación funcional en Java: de lambdas a Stream API

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción a la programación funcional en Java



Durante mucho tiempo, Java se asoció exclusivamente con la programación orientada a objetos (POO). Sin embargo, con el lanzamiento de Java 8 en 2014, el lenguaje dio un gran salto hacia el paradigma funcional. Las expresiones lambda, las interfaces funcionales y Stream API cambiaron radicalmente el enfoque de escritura de código, haciéndolo más conciso, legible y menos propenso a errores.



La programación funcional en Java no reemplaza a la POO, sino que es un poderoso complemento. Permite escribir código declarativo, donde describes qué se debe hacer, no cómo. En este artículo, analizaremos los conceptos clave que te ayudarán a dominar el estilo funcional en Java y mostraremos ejemplos prácticos.



1. Expresiones lambda e interfaces funcionales



La base de la programación funcional en Java son las expresiones lambda — una forma compacta de implementar funciones anónimas. Sintácticamente, una lambda consta de una lista de parámetros, una flecha (->) y un cuerpo:



(parámetros) -> { cuerpo }


Las lambdas siempre trabajan junto con interfaces funcionales. Una interfaz funcional es una interfaz que contiene exactamente un método abstracto (por ejemplo, Runnable, Comparator, Predicate).



Ejemplo práctico: reemplazo de una clase anónima



Comparemos el enfoque antiguo (POO) con el nuevo (funcional):



// Forma antigua (clase anónima)Runnable taskOld = new Runnable() {    @Override    public void run() {        System.out.println("¡Hola desde una clase anónima!");    }};

// Forma nueva (lambda)Runnable taskNew = () -> System.out.println("¡Hola desde una lambda!");

// EjecucióntaskNew.run();


Como puedes ver, la lambda redujo el código de 6 líneas a 1, manteniendo toda la funcionalidad.



Interfaces funcionales incorporadas (paquete java.util.function)



Java proporciona un rico conjunto de interfaces incorporadas. Aquí están las cuatro principales:



  • Predicate<T> — recibe un objeto, devuelve un boolean. Se usa para filtrar.
  • Function<T, R> — recibe un objeto de un tipo, devuelve un objeto de otro tipo. Para transformaciones.
  • Consumer<T> — recibe un objeto, no devuelve nada (void). Para efectos secundarios (imprimir en pantalla).
  • Supplier<T> — no recibe nada, devuelve un objeto. Para generación perezosa de datos.


Ejemplo con Predicate:



import java.util.function.Predicate;

public class Main { public static void main(String[] args) { Predicate<Integer> isEven = n -> n % 2 == 0; System.out.println(isEven.test(10)); // true System.out.println(isEven.test(7)); // false }}


2. Stream API: trabajo con colecciones en estilo funcional



Stream API es la joya de la programación funcional en Java. Un flujo (Stream) es una secuencia de elementos que admite operaciones secuenciales y paralelas. La principal ventaja: no modificas los datos originales, sino que creas un nuevo resultado.



Stream API se basa en tres etapas:

  1. Creación del flujo (desde una colección, array o generador).
  2. Operaciones intermedias (filtrado, ordenación, transformación). Devuelven un nuevo Stream.
  3. Operación terminal (recopilación del resultado, conteo, búsqueda). Finaliza el flujo.


Ejemplo: filtrado y transformación de una lista



Supongamos que tenemos una lista de cadenas y queremos obtener solo aquellas que tengan más de 3 caracteres, convertirlas a mayúsculas y ordenarlas.



import java.u                

Blogs

Book Recommendations