No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Aprende Inglés, Desarrollo Web, AI, Ciberseguridad y mucho más.

Antes: $249

Currency
$209
Comienza ahora

Termina en:

1 Días
13 Hrs
14 Min
24 Seg
Curso Avanzado de Java SE

Curso Avanzado de Java SE

Anahí Salgado Díaz de la Vega

Anahí Salgado Díaz de la Vega

Lambdas como variables y Recursividad

37/40
Recursos

Aportes 36

Preguntas 7

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Quiero compartir dos cosas:

  1. La notacion Dos puntos Dobles ( :: ) como ya han explicado acá, permite acceder a un método referenciandolo directamente desde la clase a la que pertenece, ejemplo:
import java.util.*; 
  
class GFG { 
  
    // static function to be called 
    static void someFunction(String s) 
    { 
        System.out.println(s); 
    } 
  
    public static void main(String[] args) 
    { 
  
        List<String> list = new ArrayList<String>(); 
        list.add("Geeks"); 
        list.add("For"); 
        list.add("GEEKS"); 
  
        // call the static method 
        // using double colon operator 
        list.forEach(GFG::someFunction); 
    } 
} 

En el ejemplo vemos que para llamar a la función someFunction hace uso de la clase GFG y la notación Dos puntos Dobles ( :: ) para referenciar directamente el método:

	GFG::someFunction

Esto en realidad difiere de las Lambas debido a que se vale del llamado por referencia al método previamente definido; mientras que la Lambda lo que hace es definir directamente en la sentencia lo que va a hacer el método.
.
2. La recursividad es la forma que tiene la programación funcional para crear estructuras de repetición (que casi siempre son necesarias a la hora de resolver problemas), y cuenta con la enorme ventaja de facilitar la lectura y comprensión del código; por ejemplo una función para calcular una sumatoria usando recursividad es tan simple y fácil de entender como esto:

public static int sumaN_recursivo(int n){
	return (n<=0) ? 0 : n + sumaN_recursivo(n-1);
}

Que en cambio se torna un poco más compleja de entender cuando en vez de usar la recursividad usamos estructuras de bucle o iteraciones (while, for). El ejemplo anterior usando iteración queda así:

public static int sumaN_iterativo(int n){
	int result= 0;
	for(int i=1; i<=n; i++){
		result +=i;
	}
	return result;
}

Como se darán cuenta tratar de hacer seguimiento de lo que hace el ciclo for y por tanto entenderlo resulta más complejo (o al menos les tomará más tiempo) que el código del ejemplo de la recursividad.
.
Sin embargo existe una razón muy poderosa por la que casí nunca se prefiere el uso de la recursividad por sobre la interación y es el error de tipo StackOverflowError, que se debe al enorme gasto de tiempo y espacio en memoria que normalmente implica que una función se llame a sí misma (recursividad). Concretamente en los casos en que los datos a procesar son significativamente grandes (o se requieren muchas repeticiones del código) los códigos recursivos tienden a “reventar” la aplicación debido a que la “Pila de datos a trabajar Desborda la capacidad de la máquina” o lo que es lo mismo StackOverflowError.
.
Nota: Ejemplos tomados de
https://www.geeksforgeeks.org/double-colon-operator-in-java/
http://www.clubdetecnologia.net/blog/2013/recursividad-iteracion/

Aquí lo que se está pasando es una referencia de método de una clase static mediante el operador ::

Por lo tanto lo que hará forEach() será aplicar ese método a cada elemento de la colección.

forEach(System.out::println)

equivale a

forEach(e -> System.out.println(e));

Las referencias a los métodos nos permiten reutilizar un método como expresión lambda. Para hacer uso de las referencias a métodos basta con utilizar la siguiente sintáxis: referenciaObjetivo::nombreDelMetodo.
(String info) -> System.out.println(info) // Expresión lambda sin referencias.
System.out::println // Expresión lambda con referencia a método estático.
Igualmente no me queda del todo claro.

Muy interesante AtomicInteger para llevar el valor del indice.

List<String> list = new ArrayList<String>();
list.add("TEXT A");
list.add("TEXT B");
list.add("TEXT C");
list.add("TEXT D");
list.add("TEXT E");
	
list.stream().filter(text -> text.contains("A")).forEach(System.out::println);
// "TEXT A"

En este articulo encontre la mejor explicacion de lo que son los Methods References.

Por Dios, qué clase de JavaScript ES6 es este jajajaja.

Excelente clase.

1 ‘for’ ambiguo y dos ‘foreach’ que hacen exactamente lo mismo, pero con recursividad.

Si entendi bien, los dos puntos :: hacen que:

  • se sobre entiende que se recibe un parametro.

  • permite mandar este parametro a la funcion siguiente, en este caso println.

No me quedo 100% claro pero si trato de explicarlo en mis palabras seria que utilizando los dos puntos, el metodo System.out.println sera llamado con el parametro recibido del foreach, sin tener que especificar el parametro ni la utilizacion de este. Es decir, solamente tendriamos que escribir con los dos puntos la funcion que nosotros queremos que se ejecute cada vez que el foreach nos da un resultado y que al mismo tiempo es el parametro de la funcion.

Notas: AtomicInteger atomicInteger = new AtomicInteger(1);
atomicInteger.getAndIncrement();
Excelente explicación, nuevo tema aprendido de los AtomicIntegers

Se puede llamar o utilizar metodos como referencia, es decir, usando los dos puntos, siempre y cuando, el método sea un void sin retorno.

: : es un operador de referencia de método en Java, es utilizado para llamar a un método, en este caso no especifica explícitamente el parámetro en el método llamado.

Saludos,

Tengo una duda entonces el forEach solo nos permite imprimir una lista ? o puedo realizar algún tipo de asignación o validación condicional ?

Muchas Gracias.

Entonces el forEach no es como en javascript que te da el value y la key? feels bad, yo pensaba que java habia mejorado pero se quedo en mitad del camino xd.

Se llama “método de referncia” y simplifica la siguiente linea de codigo

numbers.forEach(x -> System.out.println(x));

Esto quiere decir que no se necesita el nombre x para invocar println de cada uno de los elementos. Ahí es donde la referencia del método es útil: el ::operador denota que invocará el printlnmétodo con un parámetro, cuyo nombre no especifica explícitamente:

numbers.forEach(System.out::println);

Fuente: https://stackoverflow.com/questions/31020269/what-is-the-use-of-system-outprintln-in-java-8?answertab=oldest#tab-top

Uno de los cambios más bienvenidos en Java 8 fue la introducción de expresiones lambda, ya que nos permiten renunciar a clases anónimas, lo que reduce en gran medida el código repetitivo y mejora la legibilidad.

Las referencias a métodos son un tipo especial de expresiones lambda. A menudo se usan para crear expresiones lambda simples haciendo referencia a métodos existentes.

Hay cuatro tipos de referencias de métodos:

  • Métodos estáticos

  • Métodos de instancia de objetos particulares

  • Métodos de instancia de un objeto arbitrario de un tipo particular

  • Constructor

😃

**RETO** ``` {un grupo de elementos de un mismo tipo}.forEach(System.out::println) ``` Voy a explicar este código de una forma sencilla: Básicamente lo que se está indicando es que cada uno de los elementos de un grupo (en donde todos los elementos tienen el mismo tipo) se imprima con la función `println` que "se localiza" en `System.out`, la cual recibe un tipo de valor como el de los elementos del grupo que ""estamos iterando"" con el `forEach`.

RETO

{un grupo de elementos de un mismo tipo}.forEach(System.out::println)

Voy a explicar este código de una forma sencilla:
Básicamente lo que se está indicando es que cada uno de los elementos de un grupo (en donde todos los elementos tienen el mismo tipo) se imprima con la función println que “se localiza” en System.out, la cual recibe un tipo de valor como el de los elementos del grupo que ““estamos iterando”” con el forEach.

No me gusto para nada este curso, el peor

Tener muy presente este tipo de objetos como AtomicInteger, son importantes en sistemas concurrentes.

muy entendible la clase y manejo de lambda el uso de los :: muy parecido a laravel en los llamados de métodos de las clases

No entendí muy bien lo de ::

Me pueden apoyar por favor?

Gracias!

Se da por entendido no? Ya que al momento de estar trabajando con FP no estamos utilizando las iteraciones

AtomicInteger para los índices de la lista, mas información https://stackoverflow.com/questions/4818699/practical-uses-for-atomicinteger

Realmente no entiendo la sintaxis del codigo que muestran al principio

No entiendo porque no se puede hacer iteraciones ni assignaciones en las lambdas, yo lo hago en en mi codigo y no hay ningun problema. No se puede o no es recomendable? Sabeis porque no deberia?

Segun la maestra en el minuto 2:30 es posible crear lambdas a partir de clases abstractas con un solo metodo abstracto, pero eclipse me marca error diciendo que debe ser a fuerzas una functional interface. Lo mismo encontre investigando en google. Hay una manera de hacer esto con clases abstractas?

Ejemplo de código sin lambda:

mButton.setOnClickListener( new View.OnClickListener(){} );

En el ejemplo anterior se resaltan en Negritas las funciones para ilustrar la frase: Una función que recibe otra función

Con Lambdas se Ahorra Codigo…!!

los :: es una abreviacion, y significa que recorrera los todos los elementos de una coleccion, en el caso del ejemplo, los imprimira.

Tengo una duda entonces la expresión Foreach(System.out::println) , solo nos permite imprimir todo el objeto.

Genial 😃

Es algo llamado “method reference” y llamas a la función System.out.println con un parámetro que no específicas.

porque le estamos pasando la función, para que internamente forEach la llame pasando le cada elemento.

es otra forma de poder imprimir un listado.