Programación

1º DAM/DAW - Curso 2024-2025

User Tools

Site Tools


apuntes:lambdas

Interfaces funcionales, lambdas y referencias a métodos

Interfaces funcionales

  • Las interfaces funcionales son interfaces que poseen un único método abstracto (sin implementar)
  • Aparecen por primera vez en Java 8
  • Están especialmente preparadas para usarse con expresiones lambda
  • Pueden tener definidos métodos por defecto (tienen implementación)

En Java existen una serie de interfaces funcionales ya definidas especialmente útiles

  • Predicate: Evalua una condición booleana
    • IntPredicate, LongPredicate, DoublePredicate
  • Consumer: Acepta un input como entrada y no devuelve ningún resultado
    • IntConsumer, LongConsumer, DoubleConsumer
  • Function: Acepta un input como entrada y devuelve un resultado
    • IntFunction, IntToDoubleFunction, IntToLongFunction, LongFunction, LongToDoubleFunction, . . .
  • Supplier: No acepta argumentos y devuelve un resultado (al contrario que Consumer)
    • BooleanSupplier, IntSupplier, LongSupplier, DoubleSupplier
  • BiPredicate: Versión de Predicate para dos argumentos
  • BiFunction: Versión de Function para dos argumentos
Predicate<String> checkEmpty = (value) -> value.isEmpty();
System.out.println(checkEmpty.test("hola")); 
System.out.println(checkEmpty.test(""));

Pero también podemos crear las nuestras propias:

@FunctionalInterface
public interface SayMyName {
  void say(String name); 
}

Expresiones lambda

  • Aparecen por primera vez en Java 8
  • Código más compacto y limpio
  • Sustituyen al concepto de clase anónima
  • Permiten expresar las instancias de interfaces funcionales de una forma compacta
  • Su uso está especialmente extendido en el uso de Streams, donde se pueden utilizar de forma que el código queda mucho más compacto y fácil de entender
  • Cuando usamos una tenemos que imaginarnos que estamos implementando el código necesario para ejecutar luego el método que tiene por defecto asignada esa interface

La sintaxis es:

(parametros) -> (cuerpo-lambda)

Por ejemplo:

// Para ordenar una lista
listaAnimales.sort((animal1, animal2) -> (animal1.getPeso() – animal2.getPeso());
 
// Para crear un Predicate que permita evaluar una colección sobre un objeto
Animal unAnimal = new Animal(. . . .)
 
Predicate<Animal> pesoMayorQue10 = (animal) -> animal.getPeso() > 10; 
pesoMayorQue10.test(unAnimal); // true/false

Referencias a métodos

Suponiendo que tenemos una colección de cadenas, veamos unos ejemplos que nos permitan utilizar una referencia a un método:

List<String> cadenas = new ArrayList<>();

Métodos estáticos

// Utilizando una expresión lambda
cadenas.forEach((cadena) -> System.out.println(cadena))
// Equivalente utilizando referencia a método
cadenas.forEach(System.out::println)

Métodos de instancia

// Suponemos que existe una clase CadenasComparator que implementa Comparator
// Utilizando una expresión lambda
cadenas.sort((cadena1, cadena2) -> cadenasComparator.compare(cadena1, cadena2))
// Equivalente utilizando una referencia a método suponiendo que existe un objeto de la clase que implementa a CadenasComparator
cadenas.sort(cadenasComparator::compare);
// Equivalente utilizando una referencia a método
cadenas.sort(CadenasComparator::compare);

Constructores

CadenasComparator::new

© 2019-2024 Santiago Faci

apuntes/lambdas.txt · Last modified: 2023/05/28 12:04 by Santiago Faci