Metodos De Referencia Lambda - Tensho97/Aprende-a-Aprender GitHub Wiki

Cuando la expresión lambda se compone de una sola sentencia e invoca algún método existente por medio de su nombre, existe la posibilidad de escribirla usando métodos de referencia, con lo cual se logra un código más compacto y fácil de leer.

Existen tres (3) tipos de métodos de referencia y uno adicional (1) para constructores:

Métodos Estáticos

Cuando el método invocado es estático, la forma de escribir la expresión lambda usando métodos de referencia es la siguiente: NombreClase :: métodoEstático, donde NombreClase es el nombre de la clase que contiene el método y métodoEstático es el nombre del método estático a invocar.

En el siguiente ejemplo, definimos una operación de suma por medio del nuevo método estático +Integer.sum(int,int):int el cual suma los dos parámetros y retorna su resultado.

Primero veamos cómo se escribiría usando una expresión lambda:

BinaryOperator<Integer> sum = (a,b) ­> Integer.sum(a,b); 

Y ahora usando métodos de referencia:

BinaryOperator<Integer> sum = Integer::sum; 

Nótese el uso de la interface funcional java.util.function.BinaryOperator, la cual define una función que recibe dos parámetros del mismo tipo y retorna un resultado del mismo tipo de sus parámetros: +apply(T,T):T.

Métodos de instancia de un objeto

Cuando contamos con una referencia a un objeto y deseamos invocar alguno de sus métodos de instancia dentro de la expresión lambda, la forma en la que la escribiríamos usando métodos de referencia es la siguiente: RefObjeto :: métodoInstancia, donde RefObjeto es la referencia al objeto y métodoInstancia es el nombre del método a invocar.

Por ejemplo, la clase java.lang.System tiene una referencia a un objeto de tipo java.io.PrintStream denominada out, usaremos esa referencia para nuestro siguiente ejemplo.

Primero veamos cómo se escribiría usando una expresión lambda:

Consumer<Integer>  print = (a) ­> System.out.println(a); 

Y ahora usando métodos de referencia:

Consumer<Integer> print = System.out::println;

Nótese que la referencia al objeto la tenemos en System.out e invocamos su método de instancia +println(int):void

Métodos de instancia de algún tipo

Este caso es parecido al anterior, pero se diferencia en que no contamos con una referencia a un objeto, solo conocemos su tipo y podríamos escribir la expresión lambda de la siguiente forma: Tipo :: métodoInstancia, donde Tipo es la clase y métodoInstancia es el nombre del método de instancia a invocar.

El siguiente ejemplo define un java.lang.Comparator que nos permitirá comparar cadenas sin importar si son mayúsculas/minúsculas.

Primero veamos como se escribiría usando una expresión lambda:

Comparator<String>  upper = (a, b) ­> a.compareToIgnoreCase(b);

Y ahora usando métodos de referencia:

Comparator<String> upper = String::compareToIgnoreCase;

Nótese que en este caso no contamos con la referencia a un objeto como tal, pero sabemos que queremos comprar objetos de tipo String y con eso es suficiente para que podamos escribir nuestra expresión lambda usando métodos de instancia de algún tipo.

Constructores

Para el caso de constructores podemos escribir expresiones lambda como métodos de referencia de la siguiente forma: Clase :: new, donde Clase es la clase que deseamos instanciar y new es la palabra reservada ya conocida. El uso de este método de referencia para constructores que no tienen parámetros es sencillo, pero cuando los constructores tienen parámetros, debemos cambiar un poco las cosas.

Primero veamos cómo se escribiría usando una expresión lambda y un constructor sin parámetros:

Supplier<List> listSupplier = () ­> new ArrayList(); 
List  lista = listSupplier.get();

Y ahora usando métodos de referencia:

Supplier<List> listSupplier = ArrayList::new;
List lista = listSupplier.get();

Nótese el uso de la interface funcional java.util.function.Supplier y la invocación de su método +get():T el cual retorna la lista como tal.

Si el constructor recibe parámetros, tenemos que usar una interface funcional que defina un método que reciba los parámetros. En el siguiente ejemplo, vamos a crear nuevamente una lista, pero esta vez queremos que se invoque el constructor que recibe la capacidad inicial de la lista.

Primero veamos cómo se escribiría usando una expresión lambda:

Function<Integer,  List> listSupplier = (num) ­> new  ArrayList(num);
List lista = listSupplier.apply(5); 

Y ahora usando métodos de referencia:

Function<Integer, List> listSupplier = ArrayList::new; 
List  lista = listSupplier.apply(5);

Nótese el uso de la interface funcional java.util.function.Function y la invocación de su método +apply(T):R el cual recibe el parámetro que luego será pasado al constructor. Si el constructor recibe dos parámetros, se podría usar la interface funcional java.util.function.BiFunction<T,U,R> la cual define el método +apply(T,U):R que recibe dos parametros.



Autor: Richard

⚠️ **GitHub.com Fallback** ⚠️