package ar.com.javacuriosities.lambdas;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/*
* Lambda Expressions fue incluido en Java 1.8 y nos proveen una forma simple de representar
* funciones anónimas, por medio de esto logramos código mas legible, abstracto y menos propenso a errores.
* Además son ampliamente usado en Streams lo cual es otra característica agregada en Java 1.8.
*
*/
public class Lesson01Introduction {
public static void main(String[] args) {
// Generamos datos random
Random random = new SecureRandom();
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 100; i++) {
numbers.add(random.nextInt(50000));
}
System.out.println("Initial State: " + numbers);
/*
* Aca estamos usando una Lambda Expression
* Como se puede ver no definimos el tipo de datos de el parámetro
* left & right esto se debe a que además se mejoro la inferencia de tipos
* y como sort recibe un comparator con el generic type de la lista ya detecta
* que solo pueden ser Integers.
* La forma de hacer esto mismo en Java 1.7 era utilizando una clase anónima o creando
* una clase que implementaba el Comparator.
* Es importante aclarar que los Lambda Expression representa un método pero no son
* asociados con una clase por lo cual reciben el nombre de funciones anónimas
*/
numbers.sort((left, right) -> left.compareTo(right));
System.out.println("Final State: " + numbers);
/*
* Ahora podemos revisar otro detalle sobre los lambda dado que cuando
* compilamos nuestra clase no vemos ninguna clase anónima o algo similar surge la duda
* como los lambdas están definido
* Para esto podemos usar el comando "javap -p <ClassName>.class"
* Si hacemos esto veremos que nuestra clase tiene métodos del estilo
*
* private static void lambda$X$Y()
* - Donde x representa el nombre del método que contiene el lambda
* - Donde y representa un numero de secuencia iniciado en 0
*
* Luego en tiempo de ejecuccion esto de resuelve con una instrucción a nivel de bytecode,
* llamada invokedynamic, esta fue incluida en Java 1.7
* Durante el runtime se genera bytecode on the fly para ejecutar estos métodos, eso hace uso
* de sun.misc.Unsafe.defineAnonymousClass() y podemos ver las clases generadas con el siguiente
* parámetro "-Djdk.internal.lambda.dumpProxyClasses=<path>"
*/
Runnable lambda = () -> System.out.println("Hello World");
lambda.run();
}
}