Java
Tutorial Java: Funciones lambda
Java funciones lambda: uso y ejemplos. Aprende a usar funciones lambda en Java con ejemplos prácticos y detallados.
Aprende Java GRATIS y certifícateJava SE, como lenguaje de programación, siempre ha sido conocido por su orientación a objetos. Sin embargo, con la introducción de Java 8, se agregaron varios conceptos de programación funcional, incluidas las funciones lambda. Las funciones lambda son una adición significativa que permite un nuevo estilo de programación en Java.
Introducción a las Funciones Lambda
Las funciones lambda, también conocidas como cierres, son una característica importante de la programación funcional y se introdujeron en Java en su versión 8. Permiten definir métodos anónimos, es decir, métodos sin nombre que pueden ser utilizados para implementar una interfaz funcional, una interfaz con un solo método abstracto.
La sintaxis de una función lambda en Java es la siguiente:
(parametro1, parametro2, ...) -> { cuerpo de la funcion }
Donde:
- Los parámetros se escriben entre paréntesis y separados por comas.
- La flecha
->
separa los parámetros del cuerpo de la función. - El cuerpo de la función puede contener cualquier cantidad de sentencias y se encierra entre llaves.
Por ejemplo, se puede definir una función lambda para implementar una interfaz funcional Runnable
de la siguiente manera:
Runnable r = () -> System.out.println("Hola mundo!");
¿Por qué se necesitan las funciones lambda?
Las funciones lambda ayudan a simplificar el código y facilitan la programación funcional en Java. A menudo se utilizan para implementar interfaces funcionales de una manera más concisa y legible que las clases anónimas. Además, las funciones lambda se pueden pasar como argumentos a métodos o almacenar en variables, lo que permite tratar la funcionalidad como si fuera un tipo de dato.
Por ejemplo, considere la interfaz Comparator
de Java que tiene un único método compare
. Sin las funciones lambda, tendríamos que implementar la interfaz utilizando una clase anónima de la siguiente manera:
Comparator<String> comparator = new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
};
Con las funciones lambda, la implementación se simplifica considerablemente:
Comparator<String> comparator = (s1, s2) -> Integer.compare(s1.length(), s2.length());
Las funciones lambda son especialmente útiles en el contexto de las nuevas Streams API y las operaciones de colección paralela en Java 8, ya que permiten definir de manera concisa el comportamiento de las operaciones a realizar.
Tipos de Funciones Lambda
Las funciones lambda en Java pueden ser de diferentes tipos, dependiendo de sus parámetros y su valor de retorno.
- Funciones lambda sin parámetros y sin retorno: Estas son funciones que no aceptan ningún parámetro y no devuelven ningún valor. Corresponden a las interfaces funcionales que tienen un método que no toma argumentos y tiene un tipo de retorno
void
.
Ejemplo:
Runnable r = () -> System.out.println("Función lambda sin parámetros y sin retorno.");
r.run();
- Funciones lambda con parámetros y sin retorno: Estas funciones aceptan uno o más parámetros, pero no devuelven ningún valor. Corresponden a las interfaces funcionales que tienen un método que toma uno o más argumentos y tiene un tipo de retorno
void
.
Ejemplo:
Consumer<String> c = (s) -> System.out.println("Hola " + s);
c.accept("mundo");
- Funciones lambda sin parámetros y con retorno: Estas funciones no aceptan ningún parámetro pero devuelven un valor. Corresponden a las interfaces funcionales que tienen un método que no toma argumentos pero devuelve un valor.
Ejemplo:
Supplier<String> s = () -> "Función lambda sin parámetros y con retorno.";
System.out.println(s.get());
- Funciones lambda con parámetros y con retorno: Estas funciones aceptan uno o más parámetros y devuelven un valor. Corresponden a las interfaces funcionales que tienen un método que toma uno o más argumentos y devuelve un valor.
Ejemplo:
Function<String, Integer> f = (s) -> s.length();
System.out.println(f.apply("Hola mundo"));
Interfaces Funcionales
Las funciones lambda en Java están estrechamente vinculadas a las interfaces funcionales. Una interfaz funcional es una interfaz que tiene exactamente un método abstracto. Aunque puede tener cualquier número de métodos predeterminados o estáticos. Java 8 introdujo varias interfaces funcionales en el paquete java.util.function
, como Predicate
, Function
, Consumer
, Supplier
, etc.
Las interfaces funcionales se pueden implementar utilizando funciones lambda, lo que permite una mayor flexibilidad y expresividad en la programación.
La interfaz Consumer
La interfaz Consumer
representa una operación que acepta un solo argumento de entrada y no devuelve ningún resultado. Su método abstracto es void accept(T t)
.
Por ejemplo, para imprimir todos los elementos de una lista, podríamos usar una función lambda para implementar un Consumer
de la siguiente manera:
List<String> lista = Arrays.asList("Hola", "mundo", "lambda");
Consumer<String> c = (s) -> System.out.println(s);
lista.forEach(c);
La interfaz Predicate
La interfaz Predicate
representa una condición (o predicado) que un objeto dado de tipo T puede cumplir. Su método abstracto es boolean test(T t)
.
Por ejemplo, para filtrar todos los números pares de una lista, podríamos usar una función lambda para implementar un Predicate
de la siguiente manera:
List<Integer> lista = Arrays.asList(1, 2, 3, 4, 5, 6);
Predicate<Integer> p = (i) -> i % 2 == 0;
lista.stream().filter(p).forEach(System.out::println);
La interfaz Function
La interfaz Function
representa una función que acepta un argumento y produce un resultado. Su método abstracto es R apply(T t)
.
Por ejemplo, para convertir todos los elementos de una lista en mayúsculas, podríamos usar una función lambda para implementar una Function
de la siguiente manera:
List<String> lista = Arrays.asList("hola", "mundo", "lambda");
Function<String, String> f = (s) -> s.toUpperCase();
lista.stream().map(f).forEach(System.out::println);
La interfaz Supplier
La interfaz Supplier
representa una operación que no toma ningún argumento pero produce un resultado. Su método abstracto es T get ()
.
Por ejemplo, para generar una serie de números aleatorios, podríamos usar una función lambda para implementar un Supplier
de la siguiente manera:
Supplier<Double> s = () -> Math.random();
Stream.generate(s).limit(5).forEach(System.out::println);
Conclusiones
Las funciones lambda y las interfaces funcionales han traído a Java la capacidad de escribir código de una manera más funcional y declarativa. No solo simplifican el código, sino que también facilitan la programación concurrente y paralela, lo que es fundamental en el mundo de hoy con sus aplicaciones cada vez más demandantes en términos de rendimiento.
Las funciones lambda se utilizan ampliamente en la Streams API, que es una de las principales adiciones a Java 8 para facilitar el procesamiento de conjuntos de datos de manera eficiente y paralela.
Aunque las funciones lambda pueden hacer que el código sea más conciso y fácil de leer, también pueden dificultar el seguimiento del flujo de control si se abusa de ellas. Por lo tanto, siempre es importante usarlas con moderación y mantener en mente las mejores prácticas de programación.
Ejercicios de esta lección Funciones lambda
Evalúa tus conocimientos de esta lección Funciones lambda con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Clases abstractas
Streams: reduce()
Streams: flatMap()
Llamada y sobrecarga de funciones
Métodos referenciados
Métodos de la clase String
Representación de Fecha
Operadores lógicos
Tipos de datos
Estructuras de iteración
Streams: forEach()
Objetos
Funciones lambda
Uso de Scanner
CRUD en Java de modelo Customer sobre un ArrayList
Tipos de variables
Streams: collect()
Operadores aritméticos
Interfaz funcional Consumer
API java.nio 2
API Optional
Interfaz funcional Function
Encapsulación
Interfaces
Uso de API Optional
Representación de Hora
Herencia básica
Clases y objetos
Interfaz funcional Supplier
HashMap
Sobrecarga de métodos
Polimorfismo de tiempo de ejecución
OOP en Java
Creación de Streams
Streams: min max
Métodos avanzados de la clase String
Polimorfismo de tiempo de compilación
Excepciones
Herencia avanzada
Estructuras de selección
Uso de interfaces
HashSet
Objeto Scanner
Streams: filter()
Operaciones de Streams
Interfaz funcional Predicate
Streams: sorted()
Configuración de entorno
CRUD en Java de modelo Customer sobre un HashMap
Uso de variables
Clases
Streams: distinct()
Streams: count()
ArrayList
Datos de referencia
Interfaces funcionales
Métodos básicos de la clase String
Instalación
Funciones
Estructuras de control
Herencia de clases
Streams: map()
Funciones y encapsulamiento
Streams: match
Gestión de errores y excepciones
Datos primitivos
Todas las lecciones de Java
Accede a todas las lecciones de Java y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Javascript
Sintaxis
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Funciones Cierre (Closure)
Sintaxis
Funciones Flecha
Programación Funcional
Filtrado Con Filter() Y Find()
Programación Funcional
Transformación Con Map()
Programación Funcional
Reducción Con Reduce()
Programación Funcional
Clases Y Objetos
Programación Orientada A Objetos
Excepciones
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Array
Estructuras De Datos
Conjuntos Con Set
Estructuras De Datos
Mapas Con Map
Estructuras De Datos
Manipulación Dom
Dom
Selección De Elementos Dom
Dom
Modificación De Elementos Dom
Dom
Eventos Del Dom
Dom
Callbacks
Programación Asíncrona
Promises
Programación Asíncrona
Async / Await
Programación Asíncrona
Instalación De Java
Introducción Y Entorno
Configuración De Entorno Java
Introducción Y Entorno
Ecosistema Jakarta Ee De Java
Introducción Y Entorno
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Excepciones
Programación Orientada A Objetos
Clases Y Objetos
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Clases Abstractas
Programación Orientada A Objetos
Interfaces
Programación Orientada A Objetos
Sobrecarga De Métodos
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
La Clase Scanner
Programación Orientada A Objetos
Métodos De La Clase String
Programación Orientada A Objetos
Listas
Framework Collections
Conjuntos
Framework Collections
Mapas
Framework Collections
Funciones Lambda
Programación Funcional
Interfaz Funcional Consumer
Programación Funcional
Interfaz Funcional Predicate
Programación Funcional
Interfaz Funcional Supplier
Programación Funcional
Interfaz Funcional Function
Programación Funcional
Métodos Referenciados
Programación Funcional
Creación De Streams
Programación Funcional
Operaciones Intermedias Con Streams: Map()
Programación Funcional
Operaciones Intermedias Con Streams: Filter()
Programación Funcional
Operaciones Intermedias Con Streams: Distinct()
Programación Funcional
Operaciones Finales Con Streams: Collect()
Programación Funcional
Operaciones Finales Con Streams: Min Max
Programación Funcional
Operaciones Intermedias Con Streams: Flatmap()
Programación Funcional
Operaciones Intermedias Con Streams: Sorted()
Programación Funcional
Operaciones Finales Con Streams: Reduce()
Programación Funcional
Operaciones Finales Con Streams: Foreach()
Programación Funcional
Operaciones Finales Con Streams: Count()
Programación Funcional
Operaciones Finales Con Streams: Match
Programación Funcional
Api Optional
Programación Funcional
Api Java.nio 2
Entrada Y Salida (Io)
Api Java.time
Api Java.time
Certificados de superación de Java
Supera todos los ejercicios de programación del curso de Java y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender la definición y sintaxis de las funciones lambda en Java.
- Aprender a implementar funciones lambda de diferentes tipos.
- Conocer la relación entre las funciones lambda y las interfaces funcionales.
- Aprender a usar las funciones lambda con las interfaces funcionales estándar de Java: Consumer, Predicate, Function y Supplier.
- Entender el uso y beneficios de las funciones lambda en el contexto de la Streams API y la programación paralela.