Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
What to Upload to SlideShare
What to Upload to SlideShare
Loading in …3
×
1 of 53

Java 8 introducción a expresiones lambdas y api stream

0

Share

Download to read offline

Gentil introducción a Expresiones Lambdas y API Stream. Mi presentación en el Seminario Desarrollo de Software Local en el marco de la República Digital.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Java 8 introducción a expresiones lambdas y api stream

  1. 1. Java 8: Introducción a Expresiones Lambdas y API Stream Eudris Cabrera @eudriscabrera 26 Abril 2017, UASD,Santo Domingo, R. D.
  2. 2. Eudris Cabrera Graduado de Ingeniería Telemática en la PUCMM. Entusiasta de la tecnología y el software libre, desarrollador Java, instructor ocasional (Java / Linux), aficionado del béisbol/sóftbol y los bailes latinos. En el tiempo libre, escribe artículos, realiza charlas, participa en eventos tecnológicos y ayuda en la revisión de documentación técnica en el mundo Java y el código abierto.
  3. 3. Breve Reseña sobre Java Expresiones Lambda Introducción al Stream API Conceptos Avanzados sobre Lambda y API Stream Consejos Prácticos Agenda
  4. 4. ● Java fue inventado como un lenguaje orientado a objeto. ● Utiliza una máquina virtual para su ejecución (JVM) ● La plataforma java está dividida en Java SE, Java EE, Java ME y Javafx ● ~ 2005 con Java 5 se introducen cambios significativos. ○ Genéricos ○ Loop Mejorado ○ Anotaciones ○ Enumeraciones ○ Mejora para la concurrencia (AtomicInteger) Breve Reseña sobre Java James Gosling Creador de Java en los años 90's
  5. 5. Popularidad del Lenguaje Java TIOBE Index lo sitúa en el primer lugar para el mes de Abril del 2017. http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html Githut Info* lo sitúa en el segundo lugar para el mes de Abril del 2017, muy cercano a Javascript, quien ocupa el primer lugar. http://githut.info *Githut Info es un espacio que muestra el uso de los lenguajes de programación dentro de la plataforma GitHub.
  6. 6. Java SE 8 Liberado en marzo del 2014, es la plataforma que incluye la actualización más grande para el modelo de programación Java desde el lanzamiento de la plataforma en 1996. Incluye nuevas funcionalidades e incorpora las características de los lenguaje funcionales.
  7. 7. Ejemplo Antes de Java 8 public void printTeamsHasNotWonWorldSeries(List<Team> teams){ for (Team team : teams) { if(!team.isHasWonWoldSeries()){ System.out.println(""+ team.toString()); } } } Cuales desventajas presenta esta solución ?
  8. 8. Ejemplo Solución usando clases anonimas public void printTeamsWithPredicate(List<Team> teams, Predicate<Team> tester){ for (Team t : teams) { if(tester.test(t)){ System.out.println(""+ t.toString()); } } } Predicate<Team> hasNotWonWS = new Predicate<Team>() { @Override public boolean test(Team t) { return !t.isHasWonWoldSeries(); } }; printTeamsWithPredicate(teams, hasNotWonWS);
  9. 9. Funciones como entidades de primer nivel La programación funcional establece que las funciones (métodos) sean definidas como entidades de primer nivel ¿Qué significa eso? Qué las funciones pueden ser usada de la misma forma que usamos enteros (integers) o cadenas de caracteres(strings). Se pueden pasar funciones como parámetros a otras funciones y pueden ser retornada como resultado de otras funciones.
  10. 10. Ejemplo Funciones como entidades de primer nivel printTeamsWithPredicate(teams, (Team t) -> !t.isHasWonWoldSeries()); Ejemplo básico usando expresiones lambdas. Nota: Puede parecer bastante confuso en un principio, pero ya revisaremos los conceptos y cambios en el lenguaje que nos permitirán escribir código Java de esa manera.
  11. 11. Expresiones lambdas Una expresión lambda representa una función anónima. λx → x+x Función anónima que toma un número x y devuelve el resultado x + x.
  12. 12. Desarrolló en los años 30's el "Cálculo lambda", un sistema formal en lógica matemática diseñado para investigar la definición de función, la noción de aplicación de funciones y la recursión. Alonzo Church
  13. 13. Una expresión lambda se compone de un conjunto de parámetros, un operador lambda (->) y un cuerpo de la función.
  14. 14. Sintaxis () -> System.out.println("Hello Lambda") x -> x + 10 (int x, int y) -> { return x + y; } (String x, String y) -> x.length() – y.length() (int a, int b) --> a + b (int a) --> a + 1 (int a, int b) --> { System.out.println(a + b); return a + b; } () --> new ArrayList();
  15. 15. ¿Por qué Java necesita Expresiones Lambda?
  16. 16. ● Java necesitaba cambios para simplificar la codificación paralela. ● Es muy útil para evitar tener que escribir métodos que sólo utilizamos una vez. ● Simplifica cómo pasar comportamiento como un parámetro (podemos pasar expresiones lambda a métodos como argumentos).
  17. 17. Interfaces Funcionales En Java, una interfaz funcional es, básicamente, una interfaz con un único método abstracto. Este tipo de interfaces también son conocidos como tipos SAM (Single Abstract Method). @FunctionalInterface public interface Runnable { public abstract void run(); } Runnable r = () -> System.out.println("Hello Lambda");
  18. 18. java.util.function ● Predicate<T> - Recibe un argumento tipo T y retorna un booleano. ● Consumer<T> - una acción que se realiza sobre un objeto ● Function<T,R> - a funcion que transforma un valor T a R ● Supplier<T> - provee una instancia de T (como un factory). ● UnaryOperator<T> - Forma especializada de Function. Recibe un valor T como argumento y retorna del un valor del mismo tipo T. ● BinaryOperator<T> - Forma especializada de BiFunction. Recibe dos argumentos y retorna un resultado, todos del mismo tipo.
  19. 19. Metodos Predeterminados("Default") ● Tradicionalmente, las interfaces no pueden tener definiciones de método (sólo declaraciones). ● Métodos predeterminados (Default) permite realizar implementaciones por defecto dentro de una interfaz. public interface A { default void foo() { System.out.println("Calling A.foo()"); } } public class Clazz implements A { }
  20. 20. Method References Nos permiten utilizar un método como una expresión lambda. Formato: target_reference::method_name class Person { private String name; private int age; public int getAge() {return this.age;} public String getName() {return this.name;} } Person[] people = ...; Comparator<Person> byName = Comparator.comparing(Person::getName); Arrays.sort(people, byName);
  21. 21. Method References (Tipos) ● Método estático (ClassName::methName) ● Un método de instancia de un objeto particular (instanceRef::methName) ● Un método super de un objeto particular (super::methName) ● Un método de instancia de un objeto arbitrario de un tipo particular (ClassName::methName) ● Un constructor de una clase (ClassName::new) ● Un constructor de un arreglo (TypeName[]::new)
  22. 22. Introducción al API Stream Stream: ● Representa una abstracción para especificar cálculos agregados (acumulativos). ● Simplifica la descripción de los cálculos agregados (laziness,paralelismo).
  23. 23. Elementos de un Stream Un Stream se compone de 3 elementos: ● Un origen ● Cero o más operaciones intermedias ● Una operación final (salida o un resultado)
  24. 24. Ejemplo long totalEquipos = teams.stream() .filter(t -> t.isHasWonWoldSeries()) .mapToInt(Team::getLastTimeWonWorldSeries) .count(); Source Intermediate operations Terminal operation
  25. 25. java.util.stream filter/map/reduce para Java
  26. 26. java.util.stream List<MLBTeam> teams = ..; // sequential version Stream stream = students.stream(); //parallel version Stream parallelStream = students.parallelStream();
  27. 27. java.util.stream Stream Sources (Origen) ● Collections ● Generadores (Generators) ● Otros Streams
  28. 28. Ejemplo Antes de Java 8 Collection<Team> worldSeriesWinners = new ArrayList<>(); for (Team team : teams) { if (team.isHasWonWoldSeries()) { worldSeriesWinners.add(team); } } Java 8 Collection<Team> worldSeriesWinners = teams .stream() .filter(p -> p.isHasWonWoldSeries()) .collect(Collectors.toList());
  29. 29. Ejemplo Procesar la siguiente lista para que solamente contenga cadena de caracteres impares y en letra minúscula. List<String> list = Arrays.asList("BarCamp", "MongoDB", "10Gen", "TokuMX", "Nagios", "PUCMM", "Ruby", "JSON", "JSON"); Solución usando clase anónima List<String> newList = list .stream() .filter(new Predicate<String>() { @Override public boolean test(String t) { return (t.length() % 2)==1; } }).map(String::toLowerCase) .collect(Collectors.toList()); Solución usando expresiones lambdas List<String> newList = list .stream() .filter(s -> (s.length() % 2)==1) .map(String::toLowerCase) .collect(Collectors.toList());
  30. 30. Ejemplo Usando Generadores (Generators) OptionalInt one = IntStream.generate(() -> 1) .limit(10) .distinct() .findFirst();
  31. 31. java.util.stream Operaciones Intermedias ● .filter ● .map ● .flatMap ● .peek ● .distinct ● .sorted ● .limit ● .substream
  32. 32. Ejemplo a) filter(Predicate predicate) OptionalInt oldestYear = teams.stream() .filter(t -> t.isHasWonWoldSeries()) .mapToInt(Team::getLastTimeWonWorldSeries) .min(); b) map(Function<? super T, ? extends R> mapper) List<String> list = Arrays.asList("BarCamp", "MongoDB", "10Gen", "TokuMX", "Nagios", "PUCMM", "Ruby", "JSON", "JSON"); List<String> newList = list .stream() .filter(s -> (s.length() % 2)==1) .map(String::toLowerCase) .collect(Collectors.toList()); OptionalInt one = IntStream .generate(() -> 1) .limit(10) .distinct() .findFirst(); limit(long maxSize) distinct()
  33. 33. java.util.stream Operaciones Finales (Terminal Operations) ● reducers like reduce(), count(), findAny(), findFirst() ● collectors (collect()) ● forEach ● iterators
  34. 34. Ejemplo Creación de un Stream vacío Stream<String> emptyStream = Stream.empty(); long val = emptyStream.count(); Suma de arreglo de enteros int[] numbers = {1, 2, 3, 4, 5, 6, 7}; int sum = Arrays.stream(numbers).sum(); Convertir Stream a List List<String> abc = Stream.of("a", "b", "c") .collect(Collectors.toList()); Usando operación count long count = Stream.of("one").count();
  35. 35. Ejemplo Usando forEach(Consumer c) List<Team> teams = new ArrayList<>(); teams.add(new Team("STL", "St. Louis Cardinals", true, 2011)); teams.add(new Team("NYM", "NY Mets", true, 1986)); teams.add(new Team("LAA", "LA Angels", true, 2002)); teams.add(new Team("WSN", "Washington Nationals", false, 0)); teams.add(new Team("LAD", "LA Dodgers", false, 0)); teams.forEach(p -> System.out.println(p));
  36. 36. Streams de objetos y tipos primitivos ● Java tiene valores primitivos, así como tipos de objetos. ● Para mejorar la eficiencia de Stream tenemos tres Stream de tipos primitivos ○ IntStream, DoubleStream, LongStream ● Pueden usarse junto a los métodos mapToInt(), mapToDouble(), mapToLong()
  37. 37. Ejemplo Trabajando con mapToInt(ToIntFunction<T>) int highScore = students.stream() .filter(s -> s.graduationYear() == 2015) .mapToInt(s -> s.getScore()) .max(); OptionalInt oldestYear = teams.stream() .filter(t -> t.isHasWonWoldSeries()) .mapToInt(Team::getLastTimeWonWorldSeries) .min(); Method References
  38. 38. Nuevos métodos útiles en Java 8 que pueden utilizar Lambdas Iterable Iterable.forEach(Consumer c) Collection Collection.removeIf(Predicate p) List List.replaceAll(UnaryOperator o) List.sort(Comparator c) Reemplaza "Collections.sort(List l, Comparator c)"
  39. 39. Ejemplo Usando Collection.removeIf(Predicate p) List<Person> personList = new ArrayList<>(); personList.add(new Person("Wilson",35)); personList.add(new Person("Peter",25)); personList.add(new Person("Jones",27)); Usando Predicate como una clase anónima personList.removeIf(new Predicate<Person>() { @Override public boolean test(Person person) { return "Jones".equals(person.getName()); } }); Usando Predicate como expresion Lambda. 1. personList.removeIf((Person person) -> "Jones".equals(person.getName())); 2. personList.removeIf(person -> "Jones".equals(person.getName()));
  40. 40. Ejemplo Procesar la siguiente lista para que solamente contenga cadena con letra mayúscula. Antes de Java 8 List<String> list = Arrays.asList("Alfa", "Bravo", "Charlie", "Delta", "Echo", "Golf"); List<String> listUC=Lists.newArrayList(); for (ListIterator<String> it = list.listIterator(); it.hasNext();) { listUC.add(it.next().toUpperCase()); } Usando List.replaceAll(UnaryOperator o) list.replaceAll(String::toUpperCase); Method References
  41. 41. Ejemplo Ordenar la siguiente lista por nombre de personas. List<Person> personList = new ArrayList<>(); personList.add(new Person("Wilson",35)); personList.add(new Person("Peter",25)); personList.add(new Person("Jones",27)); Java 8 Collections.sort(personList, (Person p1, Person p2) -> p1.getName().compareTo(p2.getName())); Usando el método por defecto Comparator.comparing 1. personList.sort(Comparator.comparing((Person p) -> p.getName())); 2. personList.sort(Comparator.comparing(p -> p.getName()));
  42. 42. Ejemplo Ordenar la siguiente lista por nombre de personas. List<Person> personList = new ArrayList<>(); personList.add(new Person("Wilson",35)); personList.add(new Person("Peter",25)); personList.add(new Person("Jones",27)); Java 8 Comparación de dos niveles personList.sort(Comparator.comparing(Person::getAge).thenComparing(Person::getName)); Usando import estático personList.sort(comparing(Person::getAge).thenComparing(Person::getName)); methods references
  43. 43. Usando colectores (collectors) List<String> teamsWithNull = Lists.newArrayList(null, "NY Mets", null, "Washington Nationals", "LA Angels", null); List<String> filterStrings = teamsWithNull .stream() .filter(p -> p != null) .collect(Collectors.toList()); Convertir a un List sin valores nulos
  44. 44. Usando colectores (collectors) Antes de Java 8 Map<String, Team> mappedTeams = new HashMap<>(); for (Team team : teams) { mappedTeams.put(team.getTeamId(), team); } Java 8 Map<String, Team> mappedTeams = teams .stream() .collect(Collectors.toMap(Team::getTeamId, (p) -> p)); Convertir un List a un Map
  45. 45. Depuración (Debugging) Una forma de hacer depuración de aplicaciones que usen lambas y Streams es usando el método +peek(Consumer<T>):Stream<T> , el cuál es una operación intermedia y por lo tanto no interrumpe el procesamiento del Stream. List<String> newList1 = list .stream() .filter(s -> (s.length() % 2)==1) .map(String::toLowerCase) .peek(System.out::println) .collect(Collectors.toList()); Colocar un breakpoint list .stream() .filter(s -> (s.length() % 2)==1) .map(String::toLowerCase) .peek(s -> s.toString()) .collect(Collectors.toList());
  46. 46. Depuración(Debugging) Algunas veces hacer debugging con expresiones lambdas resulta ser un poco tedioso. Las expresiones lambdas no se compilan como las clases anónimas, sino que son compiladas con llamadas a invokedynamic y su implementación se hace en tiempo de ejecución. Una solución alternativa a estos casos es la siguiente: - Extraer el código de una expresión Lambda en un método separado. - Sustituir la expresión Lambda con method reference por un nuevo método. - Establecer puntos de interrupción en las sentencias en el nuevo método. - Examinar el estado del programa utilizando depurador.
  47. 47. Consejos Prácticos ● Streams pueden ser infinitos, así como finitos. No existe el concepto de "ruptura" de un Stream. Utilice la operación final (terminal) correspondiente para detener el procesamiento O utilice el Stream de forma infinita. ● Evite forEach (excepto en casos especiales) ● Necesitas pensar en programación funcional más que programación imperativa (trate de dejar de pensar en los bucles). ● Piense en la forma de abordar los problemas utilizando recursividad.
  48. 48. ¿Preguntas?
  49. 49. ¡Gracias por Acompañarnos!
  50. 50. Referencias Libros: Functional Programming in Java (Dr. Venkat Subramaniam) Enlaces: http://slidedeck.io/DDuarte/java8-slides http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html https://dzone.com/articles/java-lambda-expressions-basics http://www.oracle.com/technetwork/es/articles/java/expresiones-lambda-api-stream-java-2633852-esa.html http://www.oracle.com/technetwork/es/articles/java/expresiones-lambda-api-stream-java-2737544-esa.html http://www.infoq.com/presentations/java-8-lambda-streams http://www.infoq.com/articles/Java-8-Lambdas-A-Peek-Under-the-Hood
  51. 51. https://github.com/ecabrerar/java-8-mas-alla-de-las-expresiones-lambda Código fuente de los ejemplos en GitHub
  52. 52. Asuntos Legales Todas las marcas registradas, así como todos los logotipos, imágenes, fotografías, audio y vídeos mostrados en esta presentación son propiedad de sus respectivos propietarios y/o representantes. Su utilización es solamente para fines ilustrativos.
  53. 53. @eudriscabrera @eudris @ecabrerar @eudriscabrera Eudris Cabrera Rodríguez Ingeniero Telemático Desarrollador de Software / Consultor Informático eudris@gmail.com https://www.linkedin.com/in/eudriscabrera http://www.slideshare.net/eudris https://twitter.com/eudriscabrera https://github.com/ecabrerar

×