Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Workshop: Lambdas y Stream API en Java 8

2.544 Aufrufe

Veröffentlicht am

Workshop sobre Lambdas y el Stream API de Java 8

Veröffentlicht in: Software
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download Full EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download doc Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download Full EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download doc Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download Full EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download doc Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier

Workshop: Lambdas y Stream API en Java 8

  1. 1. LAMBDAS & STREAM API JAVA 8 @SuperSerch
  2. 2. INTRODUCCIÓN ¿POR QUÉ TENER LAMBDAS Y STREAMS? ▸ Facilitar la programación concurrente ▸ Reducir los errores al programar iteraciones de colecciones
  3. 3. CASO DE EJEMPLO PERSON class Person { int getAge(); Sex getSex(); PhoneNumber getPhoneNumber(); EmailAddr getEmailAddr(); PostalAddr getPostalAddr(); ... } enum Sex { FEMALE, MALE }
  4. 4. CASO DE EJEMPLO ROBOCALL - PERSONAS EN EDAD DE CONDUCIR class MyApplication { List<Person> list = ... void robocallEligibleDrivers() { ... } ... }
  5. 5. CASO DE EJEMPLO ROBOCALL - PERSONAS EN EDAD DE CONDUCIR void robocallEligibleDrivers() { for (Person p : list) { if (p.getAge()>=16){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } }
  6. 6. CASO DE EJEMPLO ROBOCALL - PERSONAS EN EDAD DE VOTAR
  7. 7. CASO DE EJEMPLO ROBOCALL - PERSONAS EN EDAD DE VOTAR void robocallEligibleVoters() { for (Person p : list) { if (p.getAge()>=18){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } }
  8. 8. CASO DE EJEMPLO ROBOCALL - PERSONAS EN EDAD DE BEBER
  9. 9. CASO DE EJEMPLO ROBOCALL - PERSONAS EN EDAD DE BEBER void robocallEligibleDrinkers() { for (Person p : list) { if (p.getAge()>=21){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } }
  10. 10. CASO DE EJEMPLO ROBOCALL - PERSONAS EN EDAD DE BEBER void robocallEligibleDrinkers() { for (Person p : list) { if (p.getAge()>=21){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } } CÓDIGO REPETIDO
  11. 11. CASO DE EJEMPLO SOLUCIÓN PARAMETRIZAR!
  12. 12. CASO DE EJEMPLO SOLUCIÓN PARAMETRIZAR! void robocallOlderThan(int age) { for (Person p : list) { if (p.getAge()>=age){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } }
  13. 13. CASO DE EJEMPLO USANDO PARÁMETROS void robocallEligibleDrivers() { robocallOlderThan(16); } void robocallEligibleVoters() { robocallOlderThan(18); } void robocallEligibleDrinkers() { robocallOlderThan(21); }
  14. 14. CASO DE EJEMPLO CAMBIAN LOS REQUERIMIENTOS ▸ Enviar publicidad a potenciales pilotos comerciales ▸ edad mínima de 23 ▸ pero retiro mandatorio a los 65 ▸ Agregamos otro parámetro y ahora buscamos rangos ▸ usamos Integer.MAX_VALUE para el tope superior si sólo tenemos el límite inferior ▸ usamos 0 para el tope inferior si sólo tenemos el límite superior
  15. 15. CASO DE EJEMPLO CON RANGO DE EDAD void robocallAgeRange(int low, int high) { for (Person p : list) { if (low <= p.getAge() && p.getAge() < high){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } }
  16. 16. CASO DE EJEMPLO USANDO RANGO DE EDAD void robocallEligiblePilots() { robocallAgeRange(23, 65); } void robocallEligibleDrivers() { robocallAgeRange(16, Integer.MAX_VALUE); } void robocallEligibleVoters() { robocallAgeRange(18, Integer.MAX_VALUE); } void robocallEligibleDrinkers() { robocallAgeRange(21, Integer.MAX_VALUE); }
  17. 17. CASO DE EJEMPLO UN REQUERIMIENTO MÁS ▸ Enviar publicidad a obligados a cumplir servicio militar ▸ con edades entre 18 y 26 ▸ sólo hombres
  18. 18. CASO DE EJEMPLO UN REQUERIMIENTO MÁS ▸ Enviar publicidad a obligados a cumplir servicio militar ▸ con edades entre 18 y 26 ▸ sólo hombres void robocallSelectiveService() { robocallSexAgeRange(Sex.MALE, 18, 26); }
  19. 19. CASO DE EJEMPLO CON SEXO Y RANGO DE EDAD void robocallSexAgeRange(Sex sex, int low, int high) { for (Person p : list) { if (p.getSex() == sex && low <= p.getAge() && p.getAge() < high){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } }
  20. 20. CASO DE EJEMPLO PERO AL COLOCARLO EN LOS CASOS PREVIOS void robocallEligiblePilots() { robocallSexAgeRange(???, 23, 65); } void robocallEligibleDrivers() { robocallSexAgeRange(???, 16, Integer.MAX_VALUE); } void robocallEligibleVoters() { robocallSexAgeRange(???, 18, Integer.MAX_VALUE); } void robocallEligibleDrinkers() { robocallSexAgeRange(???, 21, Integer.MAX_VALUE); }
  21. 21. CASO DE EJEMPLO PERO AL COLOCARLO EN LOS CASOS PREVIOS void robocallEligiblePilots() { robocallSexAgeRange(???, 23, 65); } void robocallEligibleDrivers() { robocallSexAgeRange(???, 16, Integer.MAX_VALUE); } void robocallEligibleVoters() { robocallSexAgeRange(???, 18, Integer.MAX_VALUE); } void robocallEligibleDrinkers() { robocallSexAgeRange(???, 21, Integer.MAX_VALUE); }
  22. 22. CASO DE EJEMPLO INTENTO #1 DE ARREGLARLO enum Sex { FEMALE, MALE, DONT_CARE } void robocallSexAgeRange(Sex sex, int low, int high) { for (Person p : list) { if ((sex == DONT_CARE || p.getSex() == sex) && low <= p.getAge() && p.getAge() < high){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } }
  23. 23. CASO DE EJEMPLO INTENTO #1 DE ARREGLARLO enum Sex { FEMALE, MALE, DONT_CARE } void robocallSexAgeRange(Sex sex, int low, int high) { for (Person p : list) { if ((sex == DONT_CARE || p.getSex() == sex) && low <= p.getAge() && p.getAge() < high){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } }
  24. 24. CASO DE EJEMPLO INTENTO #1 DE ARREGLARLO enum Sex { FEMALE, MALE, DONT_CARE } void robocallSexAgeRange(Sex sex, int low, int high) { for (Person p : list) { if ((sex == DONT_CARE || p.getSex() == sex) && low <= p.getAge() && p.getAge() < high){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } } IMPLEMENTACIÓN CONTAMINA EL MODELO
  25. 25. CASO DE EJEMPLO INTENTO #2 DE ARREGLARLO - USAR NULL void robocallSexAgeRange(Sex sex, int low, int high) { for (Person p : list) { if ((sex == null || p.getSex() == sex) && low <= p.getAge() && p.getAge() < high){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } }
  26. 26. CASO DE EJEMPLO AL COLOCARLO EN LOS CASOS PREVIOS void robocallSelectiveService() { robocallSexAgeRange(Sex.MALE, 18, 26); } void robocallEligiblePilots() { robocallSexAgeRange(null, 23, 65); } void robocallEligibleDrivers() { robocallSexAgeRange(null, 16, Integer.MAX_VALUE); }
  27. 27. CASO DE EJEMPLO AL COLOCARLO EN LOS CASOS PREVIOS void robocallSelectiveService() { robocallSexAgeRange(Sex.MALE, 18, 26); } void robocallEligiblePilots() { robocallSexAgeRange(null, 23, 65); } void robocallEligibleDrivers() { robocallSexAgeRange(null, 16, Integer.MAX_VALUE); } ▸ Pero, ¿y si sex==null significa que no se capturó el sexo?
  28. 28. CASO DE EJEMPLO INTENTO #3 AGREGAR UN BOOLEAN void robocallSexAgeRange(Sex sex, int low, int high) { for (Person p : list) { if ((sex == null || p.getSex() == sex) && low <= p.getAge() && p.getAge() < high){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } }
  29. 29. CASO DE EJEMPLO AL COLOCARLO EN LOS CASOS PREVIOS void robocallSelectiveService() { robocallSexAgeRange(Sex.MALE, true, 18, 26); } void robocallEligiblePilots() { robocallSexAgeRange(null, false, 23, 65); } void robocallEligibleDrivers() { robocallSexAgeRange(Sex.MALE, false, 16, Integer.MAX_VALUE); }
  30. 30. CASO DE EJEMPLO AL COLOCARLO EN LOS CASOS PREVIOS void robocallSelectiveService() { robocallSexAgeRange(Sex.MALE, true, 18, 26); } void robocallEligiblePilots() { robocallSexAgeRange(null, false, 23, 65); } void robocallEligibleDrivers() { robocallSexAgeRange(Sex.MALE, false, 16, Integer.MAX_VALUE); } ▸ aún hay que poner algo en el campo de sex, incluso si es ignorado
  31. 31. CASO DE EJEMPLO AL COLOCARLO EN LOS CASOS PREVIOS void robocallSelectiveService() { robocallSexAgeRange(Sex.MALE, true, 18, 26); } void robocallEligiblePilots() { robocallSexAgeRange(null, false, 23, 65); } void robocallEligibleDrivers() { robocallSexAgeRange(Sex.MALE, false, 16, Integer.MAX_VALUE); } ▸ aún hay que poner algo en el campo de sex, incluso si es ignorado ▸ ¿Y si olvidamos cambiar el boolean al cambiar la llamada?
  32. 32. CASO DE EJEMPLO LO QUE EL CALLER QUIERE void robocallSelectiveService() { robocallMatchingPersons(*******) }
  33. 33. CASO DE EJEMPLO LO QUE EL CALLER QUIERE void robocallSelectiveService() { robocallMatchingPersons(*******) } ▸ *** dada una persona, usando características de la persona, decidir cuando esa persona deberá ser robo-llamada
  34. 34. CASO DE EJEMPLO LO QUE LA BIBLIOTECA QUIERE void robocallMatchingPersons(********) { for (Person p : list) { if (***) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } }
  35. 35. CASO DE EJEMPLO LO QUE LA BIBLIOTECA QUIERE void robocallMatchingPersons(********) { for (Person p : list) { if (***) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } }
  36. 36. CASO DE EJEMPLO LO QUE LA BIBLIOTECA QUIERE void robocallMatchingPersons(********) { for (Person p : list) { if (***) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } } ES UNA FUNCIÓN!
  37. 37. CASO DE EJEMPLO LO QUE LA BIBLIOTECA QUIERE void robocallMatchingPersons(********) { for (Person p : list) { if (***) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } } ES UNA FUNCIÓN! ▸ Función dada una persona, usando características de la persona, decidir cuando esa persona deberá ser robo-llamada ▸ El parámetro de esa función es una Persona ▸ El resultado de esa función es un boolean
  38. 38. LAMBDAS ¿QUÉ ES UNA EXPRESIÓN LAMBDA?
  39. 39. LAMBDAS ¿QUÉ ES UNA EXPRESIÓN LAMBDA? ▸ Forma matemática que define la transformación de un valor
  40. 40. LAMBDAS ¿QUÉ ES UNA EXPRESIÓN LAMBDA? ▸ Forma matemática que define la transformación de un valor ▸ A las cosas que realizan transformaciones las denominamos Funciones
  41. 41. LAMBDAS ¿QUÉ ES UNA EXPRESIÓN LAMBDA? ▸ Forma matemática que define la transformación de un valor ▸ A las cosas que realizan transformaciones las denominamos Funciones ▸ int -> int 
 Función que transforma de entero a entero
  42. 42. LAMBDAS ¿QUÉ ES UNA EXPRESIÓN LAMBDA? ▸ Forma matemática que define la transformación de un valor ▸ A las cosas que realizan transformaciones las denominamos Funciones ▸ int -> int 
 Función que transforma de entero a entero ▸ Las expresiones Lambda son la manera de agregar funciones a Java
  43. 43. LAMBDAS PROPÓSITO DE LAS EXPRESIONES LAMBDA
  44. 44. LAMBDAS PROPÓSITO DE LAS EXPRESIONES LAMBDA ▸ Proveen una manera sencilla para distribuir procesamiento específico
  45. 45. LAMBDAS PROPÓSITO DE LAS EXPRESIONES LAMBDA ▸ Proveen una manera sencilla para distribuir procesamiento específico ▸ Útiles para procesar colecciones
  46. 46. LAMBDAS PROPÓSITO DE LAS EXPRESIONES LAMBDA ▸ Proveen una manera sencilla para distribuir procesamiento específico ▸ Útiles para procesar colecciones ▸ Facilitar la cooperación entre desarrolladores y usuarios de bibliotecas
  47. 47. LAMBDAS PROPÓSITO DE LAS EXPRESIONES LAMBDA ▸ Proveen una manera sencilla para distribuir procesamiento específico ▸ Útiles para procesar colecciones ▸ Facilitar la cooperación entre desarrolladores y usuarios de bibliotecas ▸ (T p, T2 q, …) -> {bloque de código}
  48. 48. LAMBDAS ¿CÓMO REPRESENTAMOS FUNCIONES EN JAVA? new Thread(new Runnable() { public void run() { System.out.println("Estoy en otro hilo."); } }).start(); Collections.sort(people, new Comparator<Person>() { public int compare(Person x, Person y) { return x.getLastName().compareTo(y.getLastName()); } });
  49. 49. LAMBDAS LAMBDAS
  50. 50. LAMBDAS LAMBDAS ▸ Bloque de código
  51. 51. LAMBDAS LAMBDAS ▸ Bloque de código ▸ Se basan en Target Typing (Según el contexto se determina el tipo de la Lambda)
  52. 52. LAMBDAS LAMBDAS ▸ Bloque de código ▸ Se basan en Target Typing (Según el contexto se determina el tipo de la Lambda) ▸ existen en dos categorías:
  53. 53. LAMBDAS LAMBDAS ▸ Bloque de código ▸ Se basan en Target Typing (Según el contexto se determina el tipo de la Lambda) ▸ existen en dos categorías: ▸ Sin efectos colaterales
  54. 54. LAMBDAS LAMBDAS ▸ Bloque de código ▸ Se basan en Target Typing (Según el contexto se determina el tipo de la Lambda) ▸ existen en dos categorías: ▸ Sin efectos colaterales ▸ Con efectos colaterales
  55. 55. LAMBDAS LAMBDAS ▸ Bloque de código ▸ Se basan en Target Typing (Según el contexto se determina el tipo de la Lambda) ▸ existen en dos categorías: ▸ Sin efectos colaterales ▸ Con efectos colaterales ▸ Siempre asignadas a una Functional Interface
  56. 56. FUNCTIONAL INTERFACE FUNCTIONAL INTERFACE
  57. 57. FUNCTIONAL INTERFACE FUNCTIONAL INTERFACE ▸ Interfaces que tienen sólo un método abstracto.
  58. 58. FUNCTIONAL INTERFACE FUNCTIONAL INTERFACE ▸ Interfaces que tienen sólo un método abstracto. ▸ Los métodos por defecto, dado que ya están implementados, no cuentan para definir si una Interface es funcional o no
  59. 59. FUNCTIONAL INTERFACE FUNCTIONAL INTERFACE ▸ Interfaces que tienen sólo un método abstracto. ▸ Los métodos por defecto, dado que ya están implementados, no cuentan para definir si una Interface es funcional o no ▸ Si la interface declara un método abstracto, pero que sobreescribe un método de java.lang.Object, este tampoco cuenta para definir si es funcional o no
  60. 60. FUNCTIONAL INTERFACE FUNCTIONAL INTERFACE ▸ Interfaces que tienen sólo un método abstracto. ▸ Los métodos por defecto, dado que ya están implementados, no cuentan para definir si una Interface es funcional o no ▸ Si la interface declara un método abstracto, pero que sobreescribe un método de java.lang.Object, este tampoco cuenta para definir si es funcional o no ▸ Multiples Interfaces se pueden heredar y será una interface funcional si cumple con las reglas anteriores
  61. 61. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface Runnable { void run(); }
  62. 62. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface Runnable { void run(); } ✔
  63. 63. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface NonFunc { boolean equals(Object obj); }
  64. 64. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface NonFunc { boolean equals(Object obj); } ✗
  65. 65. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface Func extends NonFunc { int compare(String o1, String o2); }
  66. 66. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface Func extends NonFunc { int compare(String o1, String o2); } ✔
  67. 67. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface Comparator<T> { boolean equals(Object obj); int compare(T o1, T o2); }
  68. 68. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface Comparator<T> { boolean equals(Object obj); int compare(T o1, T o2); } ✔
  69. 69. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface Foo { int m(); Object clone(); }
  70. 70. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface Foo { int m(); Object clone(); } ✗
  71. 71. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface X { int m(Iterable<String> arg); } interface Y { int m(Iterable<String> arg); } interface Z extends X, Y {}
  72. 72. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface X { int m(Iterable<String> arg); } interface Y { int m(Iterable<String> arg); } interface Z extends X, Y {} ✔
  73. 73. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface X { Iterable m(Iterable<String> arg); } interface Y { Iterable<String> m(Iterable arg); } interface Z extends X, Y {}
  74. 74. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface X { Iterable m(Iterable<String> arg); } interface Y { Iterable<String> m(Iterable arg); } interface Z extends X, Y {} ✔
  75. 75. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface X { int m(Iterable<String> arg); } interface Y { int m(Iterable<Integer> arg); } interface Z extends X, Y {} interface X { int m(Iterable<String> arg, Class c); } interface Y { int m(Iterable arg, Class<?> c); } interface Z extends X, Y {} interface X<T> { void m(T arg); } interface Y<T> { void m(T arg); } interface Z<A, B> extends X<A>, Y<B> {}
  76. 76. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface X { int m(Iterable<String> arg); } interface Y { int m(Iterable<Integer> arg); } interface Z extends X, Y {} interface X { int m(Iterable<String> arg, Class c); } interface Y { int m(Iterable arg, Class<?> c); } interface Z extends X, Y {} interface X<T> { void m(T arg); } interface Y<T> { void m(T arg); } interface Z<A, B> extends X<A>, Y<B> {} ✗
  77. 77. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface X { int m(Iterable<String> arg); } interface Y { int m(Iterable<Integer> arg); } interface Z extends X, Y {} interface X { int m(Iterable<String> arg, Class c); } interface Y { int m(Iterable arg, Class<?> c); } interface Z extends X, Y {} interface X<T> { void m(T arg); } interface Y<T> { void m(T arg); } interface Z<A, B> extends X<A>, Y<B> {} ✗ ✗
  78. 78. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface X { int m(Iterable<String> arg); } interface Y { int m(Iterable<Integer> arg); } interface Z extends X, Y {} interface X { int m(Iterable<String> arg, Class c); } interface Y { int m(Iterable arg, Class<?> c); } interface Z extends X, Y {} interface X<T> { void m(T arg); } interface Y<T> { void m(T arg); } interface Z<A, B> extends X<A>, Y<B> {} ✗ ✗ ✗
  79. 79. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface X { long m(); } interface Y { int m(); } interface Z extends X, Y {}
  80. 80. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface X { long m(); } interface Y { int m(); } interface Z extends X, Y {} ✗
  81. 81. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface Foo<T, N extends Number> { void m(T arg); void m(N arg); } interface Bar extends Foo<String, Integer> {} interface Baz extends Foo<Integer, Integer> {}
  82. 82. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface Foo<T, N extends Number> { void m(T arg); void m(N arg); } interface Bar extends Foo<String, Integer> {} interface Baz extends Foo<Integer, Integer> {} ✗
  83. 83. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface Foo<T, N extends Number> { void m(T arg); void m(N arg); } interface Bar extends Foo<String, Integer> {} interface Baz extends Foo<Integer, Integer> {} ✗ ✗
  84. 84. FUNCTIONAL INTERFACE RECONOCIENDO UNA INTERFACE FUNCIONAL interface Foo<T, N extends Number> { void m(T arg); void m(N arg); } interface Bar extends Foo<String, Integer> {} interface Baz extends Foo<Integer, Integer> {} ✗ ✗ ✔
  85. 85. LAMBDAS SINTAXIS DE UNA LAMBDA (parameters) -> expresion (parameters) -> { statements; } //return necesario
  86. 86. LAMBDAS EJEMPLO - COMPARATOR List<Animal> farm = loadAnimals(); Collections.sort(farm, new Comparator<Animal>() { @Override public int compare(Animal a1, Animal a2) { return a1.name.compareTo(a2.name); } });
  87. 87. LAMBDAS EJEMPLO - COMPARATOR List<Animal> farm = loadAnimals(); Collections.sort(farm, (Animal a1, Animal a2) -> a1.name.compareTo(a2.name));
  88. 88. LAMBDAS EJEMPLO - COMPARATOR List<Animal> farm = loadAnimals(); Collections.sort(farm, (Animal a1, Animal a2) -> a1.name.compareTo(a2.name));
  89. 89. LAMBDAS EJEMPLO - COMPARATOR List<Animal> farm = loadAnimals(); Collections.sort(farm, (a1, a2) -> a1.name.compareTo(a2.name));
  90. 90. LAMBDAS EJEMPLOS (int x, int y) -> x + y (x, y) -> x - y () -> 10 (String s) -> System.out.println(s) x -> x * 2 c -> { int s = c.size(); c.clear(); return s; }
  91. 91. LAMBDAS ¿QUÉ ES UNA LAMBDA?
  92. 92. LAMBDAS ¿QUÉ ES UNA LAMBDA? ▸ instancias especiales de "objetos"
  93. 93. LAMBDAS ¿QUÉ ES UNA LAMBDA? ▸ instancias especiales de "objetos" ▸ con dependencias autocontenidas (capturadas)
  94. 94. LAMBDAS ¿QUÉ ES UNA LAMBDA? ▸ instancias especiales de "objetos" ▸ con dependencias autocontenidas (capturadas) ▸ diseñadas para dar soporte a la iteración interna de colecciones
  95. 95. LAMBDAS ¿QUÉ ES UNA LAMBDA? ▸ instancias especiales de "objetos" ▸ con dependencias autocontenidas (capturadas) ▸ diseñadas para dar soporte a la iteración interna de colecciones ▸ pueden ser valores de retorno
  96. 96. LAMBDAS ¿QUÉ ES UNA LAMBDA? ▸ instancias especiales de "objetos" ▸ con dependencias autocontenidas (capturadas) ▸ diseñadas para dar soporte a la iteración interna de colecciones ▸ pueden ser valores de retorno ▸ pueden serializarse (mediante un cast)
  97. 97. LAMBDAS INTERFACES FUNCIONALES EN JDK 8
  98. 98. LAMBDAS INTERFACES FUNCIONALES EN JDK 8 ▸ Supplier<T>
  99. 99. LAMBDAS INTERFACES FUNCIONALES EN JDK 8 ▸ Supplier<T> ▸ Consumer<T>
  100. 100. LAMBDAS INTERFACES FUNCIONALES EN JDK 8 ▸ Supplier<T> ▸ Consumer<T> ▸ Predicate<T>
  101. 101. LAMBDAS INTERFACES FUNCIONALES EN JDK 8 ▸ Supplier<T> ▸ Consumer<T> ▸ Predicate<T> ▸ Function<T,R>
  102. 102. LAMBDAS INTERFACES FUNCIONALES EN JDK 8 ▸ Supplier<T> ▸ Consumer<T> ▸ Predicate<T> ▸ Function<T,R> ▸ UnaryOperator<T>
  103. 103. LAMBDAS INTERFACES FUNCIONALES EN JDK 8 ▸ Supplier<T> ▸ Consumer<T> ▸ Predicate<T> ▸ Function<T,R> ▸ UnaryOperator<T> ▸ BinaryOperator<T>
  104. 104. LAMBDAS INTERFACES FUNCIONALES EN JDK 8 ▸ Supplier<T> ▸ Consumer<T> ▸ Predicate<T> ▸ Function<T,R> ▸ UnaryOperator<T> ▸ BinaryOperator<T> java.util.function
  105. 105. LAMBDAS Supplier<T>
  106. 106. LAMBDAS Supplier<T> ▸ Representa a un proveedor de objetos tipo T
  107. 107. LAMBDAS Supplier<T> ▸ Representa a un proveedor de objetos tipo T ▸ La creación del objeto T se realiza sólo hasta el momento de utilizarse
  108. 108. LAMBDAS Supplier<T> ▸ Representa a un proveedor de objetos tipo T ▸ La creación del objeto T se realiza sólo hasta el momento de utilizarse ▸ Su método funcional es Supplier.get()
  109. 109. LAMBDAS Supplier<T> ▸ Representa a un proveedor de objetos tipo T ▸ La creación del objeto T se realiza sólo hasta el momento de utilizarse ▸ Su método funcional es Supplier.get() logger.fine("Parámetro de búsqueda: "+parametro); logger.fine(()->"Parámetro de búsqueda: "+parametro); public void printOut(Supplier<String> msgSup){ if (SEND_TO_OUT) System.out.println(msgSup.get()); }
  110. 110. LAMBDAS Consumer<T>
  111. 111. LAMBDAS Consumer<T> ▸ Representa una operación que acepta un único parámetro de tipo T
  112. 112. LAMBDAS Consumer<T> ▸ Representa una operación que acepta un único parámetro de tipo T ▸ No regresa ningún resultado
  113. 113. LAMBDAS Consumer<T> ▸ Representa una operación que acepta un único parámetro de tipo T ▸ No regresa ningún resultado ▸ Se considera como una acción que produce un efecto colateral
  114. 114. LAMBDAS Consumer<T> ▸ Representa una operación que acepta un único parámetro de tipo T ▸ No regresa ningún resultado ▸ Se considera como una acción que produce un efecto colateral ▸ Su método funcional es Consumer.accept(Object)
  115. 115. LAMBDAS Consumer<T> ▸ Representa una operación que acepta un único parámetro de tipo T ▸ No regresa ningún resultado ▸ Se considera como una acción que produce un efecto colateral ▸ Su método funcional es Consumer.accept(Object) nombres.forEach(s -> System.out.println(s));
  116. 116. LAMBDAS Predicate<T>
  117. 117. LAMBDAS Predicate<T> ▸ Representa un predicado booleano de un argumento
  118. 118. LAMBDAS Predicate<T> ▸ Representa un predicado booleano de un argumento ▸ Su método funcional es Predicate.test(Object)
  119. 119. LAMBDAS Predicate<T> ▸ Representa un predicado booleano de un argumento ▸ Su método funcional es Predicate.test(Object) Stream<User> mayores = personas.stream().filter( p -> p.getAge()>18);
  120. 120. LAMBDAS Function<T,R>
  121. 121. LAMBDAS Function<T,R> ▸ Representa una función de transformación de T a R
  122. 122. LAMBDAS Function<T,R> ▸ Representa una función de transformación de T a R ▸ Regresa un objeto de tipo R
  123. 123. LAMBDAS Function<T,R> ▸ Representa una función de transformación de T a R ▸ Regresa un objeto de tipo R ▸ Su método funcional es Function.apply(Object)
  124. 124. LAMBDAS Function<T,R> ▸ Representa una función de transformación de T a R ▸ Regresa un objeto de tipo R ▸ Su método funcional es Function.apply(Object) Stream<Integer> longitudes = personas .stream() .map(u -> u.getName()==null ? 0 : u.getName().length());
  125. 125. LAMBDAS UnaryOperator<T>
  126. 126. LAMBDAS UnaryOperator<T> ▸ Representa una función de transformación de T a T
  127. 127. LAMBDAS UnaryOperator<T> ▸ Representa una función de transformación de T a T ▸ Su método funcional es UnaryOperator.apply(Object)
  128. 128. LAMBDAS BinaryOperator<T>
  129. 129. LAMBDAS BinaryOperator<T> ▸ Representa una función de Transformación de T, T a T
  130. 130. LAMBDAS BinaryOperator<T> ▸ Representa una función de Transformación de T, T a T ▸ Su método funcional es BinaryOperator.apply(Object, Object)
  131. 131. METHOD REFERENCES METHOD REFERENCES Consumer<String> consumer = s -> System.out.println(s); Consumer<String> consumer = System.out::println;
  132. 132. METHOD REFERENCES METHOD REFERENCES ▸ En algunas ocasiones sólo usamos una Lambda para llamar un método existente
 
 
 
 
 Consumer<String> consumer = s -> System.out.println(s); Consumer<String> consumer = System.out::println;
  133. 133. METHOD REFERENCES METHOD REFERENCES ▸ En algunas ocasiones sólo usamos una Lambda para llamar un método existente
 
 
 
 
 ▸ Referencias a Métodos son una forma simple y fácil de leer para implementar expresiones lambda con métodos que ya tienen nombre Consumer<String> consumer = s -> System.out.println(s); Consumer<String> consumer = System.out::println;
  134. 134. METHOD REFERENCES TIPOS DE METHOD REFERENCES
  135. 135. METHOD REFERENCES TIPOS DE METHOD REFERENCES ▸ Referencia a un método estático - ContainingClass::staticMethodName
  136. 136. METHOD REFERENCES TIPOS DE METHOD REFERENCES ▸ Referencia a un método estático - ContainingClass::staticMethodName ▸ Referencia a un método de instancia de un objeto específico - containingObject::instanceMethodName
  137. 137. METHOD REFERENCES TIPOS DE METHOD REFERENCES ▸ Referencia a un método estático - ContainingClass::staticMethodName ▸ Referencia a un método de instancia de un objeto específico - containingObject::instanceMethodName ▸ Referencia a un método de instancia de cualquier objeto de un tipo definido - ContainingType::methodName
  138. 138. METHOD REFERENCES TIPOS DE METHOD REFERENCES ▸ Referencia a un método estático - ContainingClass::staticMethodName ▸ Referencia a un método de instancia de un objeto específico - containingObject::instanceMethodName ▸ Referencia a un método de instancia de cualquier objeto de un tipo definido - ContainingType::methodName ▸ Referencia a un constructor - ClassName::new
  139. 139. OPTIONAL Optional
  140. 140. OPTIONAL Optional ▸ Contenedor de un objeto que puede o no ser null
  141. 141. OPTIONAL Optional ▸ Contenedor de un objeto que puede o no ser null ▸ Si contiene un valor, isPresent() regresa true y get() el valor
  142. 142. OPTIONAL Optional ▸ Contenedor de un objeto que puede o no ser null ▸ Si contiene un valor, isPresent() regresa true y get() el valor ▸ Es inmutable y tiene métodos para caso como: 
 orElse(T) 
 orElseGet(Supplier<? extends T> other) 
 orElseThrow(Supplier<? extends X> 
 exceptionSupplier)
  143. 143. STREAM API CASO DE EJEMPLO: CALCULAR EL PROMEDIO DE EDAD DE LOS ELEGIBLES A BEBER
  144. 144. STREAM API CASO DE EJEMPLO: CALCULAR EL PROMEDIO DE EDAD DE LOS ELEGIBLES A BEBER ... List<Person> list ... double ageAverageElegibleDrivers() { double sum = 0; int cont = 0; for (Person p : list) { if (p.getAge()>=21){ sun += p.getAge(); cont++; } } return sum/cont; }
  145. 145. STREAM API APLICANDO STREAMS
  146. 146. STREAM API APLICANDO STREAMS ... List<Person> list ... double ageAverageElegibleDrivers(){ return list.stream() .filter(p -> p.age>21) .mapToInt(p->p.getAge()) .average() .orElse(0.0); }
  147. 147. STREAM API STREAM API
  148. 148. STREAM API STREAM API ▸ Diseñado para trabajar principalmente con colecciones
  149. 149. STREAM API STREAM API ▸ Diseñado para trabajar principalmente con colecciones ▸ Provee de una manera "declarativa" de procesar una colección
  150. 150. STREAM API STREAM API ▸ Diseñado para trabajar principalmente con colecciones ▸ Provee de una manera "declarativa" de procesar una colección ▸ Se puede ver como un Iterador elegante de una colección
  151. 151. STREAM API STREAM API ▸ Diseñado para trabajar principalmente con colecciones ▸ Provee de una manera "declarativa" de procesar una colección ▸ Se puede ver como un Iterador elegante de una colección ▸ Facilita la paralelización del procesamiento de la información
  152. 152. STREAM API ¿QUÉ ES UN STREAM?
  153. 153. STREAM API ¿QUÉ ES UN STREAM? ▸ Secuencia de elementos
  154. 154. STREAM API ¿QUÉ ES UN STREAM? ▸ Secuencia de elementos ▸ No almacena valores, los genera bajo demanda
  155. 155. STREAM API ¿QUÉ ES UN STREAM? ▸ Secuencia de elementos ▸ No almacena valores, los genera bajo demanda ▸ Fuente de datos
  156. 156. STREAM API ¿QUÉ ES UN STREAM? ▸ Secuencia de elementos ▸ No almacena valores, los genera bajo demanda ▸ Fuente de datos ▸ Consumen desde una fuente de datos como Colecciones, Arreglos e I/O
  157. 157. STREAM API ¿QUÉ ES UN STREAM? (2)
  158. 158. STREAM API ¿QUÉ ES UN STREAM? (2) ▸ Operaciones de Agregación
  159. 159. STREAM API ¿QUÉ ES UN STREAM? (2) ▸ Operaciones de Agregación ▸ Operaciones estilo base de datos como: filter, map, reduce, findFirst, allMatch, sorted, …
  160. 160. STREAM API ¿QUÉ ES UN STREAM? (2) ▸ Operaciones de Agregación ▸ Operaciones estilo base de datos como: filter, map, reduce, findFirst, allMatch, sorted, … ▸ Encadenamiento
  161. 161. STREAM API ¿QUÉ ES UN STREAM? (2) ▸ Operaciones de Agregación ▸ Operaciones estilo base de datos como: filter, map, reduce, findFirst, allMatch, sorted, … ▸ Encadenamiento ▸ La mayoría de las operaciones regresan un stream, por lo que se pueden encadenar. El procesamiento se hace sólo al alcanzar una operación terminal
  162. 162. STREAM API ¿QUÉ ES UN STREAM? (3)
  163. 163. STREAM API ¿QUÉ ES UN STREAM? (3) ▸ Iteración Interna
  164. 164. STREAM API ¿QUÉ ES UN STREAM? (3) ▸ Iteración Interna ▸ La iteración es decidida internamente y reflejará la forma en que se encadenaron las operaciones
  165. 165. STREAM API STREM VS COLLECTION
  166. 166. STREAM API STREM VS COLLECTION ▸ Sin Almacenamiento
  167. 167. STREAM API STREM VS COLLECTION ▸ Sin Almacenamiento ▸ Funcionales
  168. 168. STREAM API STREM VS COLLECTION ▸ Sin Almacenamiento ▸ Funcionales ▸ Flojas
  169. 169. STREAM API STREM VS COLLECTION ▸ Sin Almacenamiento ▸ Funcionales ▸ Flojas ▸ Posiblemente Ilimitadas
  170. 170. STREAM API STREM VS COLLECTION ▸ Sin Almacenamiento ▸ Funcionales ▸ Flojas ▸ Posiblemente Ilimitadas ▸ limit(n) findFirst()
  171. 171. STREAM API STREM VS COLLECTION ▸ Sin Almacenamiento ▸ Funcionales ▸ Flojas ▸ Posiblemente Ilimitadas ▸ limit(n) findFirst() ▸ Consumibles
  172. 172. STREAM API PIPELINE
  173. 173. STREAM API PIPELINE ▸ Fuente de datos
  174. 174. STREAM API PIPELINE ▸ Fuente de datos ▸ una o varias operaciones Intermedias
  175. 175. STREAM API PIPELINE ▸ Fuente de datos ▸ una o varias operaciones Intermedias ▸ Son operaciones que regresan otro stream, por lo que se pueden encadenar, no se ejecutan sino hasta que el stream tenga una operación terminal y deberían utilizar funciones sin efectos colaterales
  176. 176. STREAM API PIPELINE ▸ Fuente de datos ▸ una o varias operaciones Intermedias ▸ Son operaciones que regresan otro stream, por lo que se pueden encadenar, no se ejecutan sino hasta que el stream tenga una operación terminal y deberían utilizar funciones sin efectos colaterales ▸ una operación Terminal
  177. 177. STREAM API PIPELINE ▸ Fuente de datos ▸ una o varias operaciones Intermedias ▸ Son operaciones que regresan otro stream, por lo que se pueden encadenar, no se ejecutan sino hasta que el stream tenga una operación terminal y deberían utilizar funciones sin efectos colaterales ▸ una operación Terminal ▸ Son operaciones que "Terminan" un stream, usualmente tienen efectos colaterales e inician el procesamiento del stream y producen un resultado
  178. 178. STREAM API ¿DE DÓNDE OBTENEMOS LOS STREAMS? (FUENTES) ▸ De una Colección usando los métodos stream() y parallelStream() ▸ De un arreglo Arrays.stream(Object[]) ▸ De las clases stream Stream.of(Object[]), IntStream.range(int, int) ▸ De un archivo BufferedReader.lines() ▸ De directorios, patrones, números aleatorios y/o creadas por nosotros
  179. 179. STREAM API APLICANDO STREAMS
  180. 180. STREAM API APLICANDO STREAMS ... List<Person> list ... double ageAverageElegibleDrivers(){ return list.stream() .filter(p -> p.age>21) .mapToInt(p->p.getAge()) .average() .orElse(0.0); }
  181. 181. STREAM API APLICANDO STREAMS ... List<Person> list ... double ageAverageElegibleDrivers(){ return list.stream() .filter(p -> p.age>21) .mapToInt(p->p.getAge()) .average() .orElse(0.0); } fuente intermedias terminal
  182. 182. STREAM API LOS STREAMS SON OBJETOS int highScore = students.stream() .filter(s -> s.gradutationYear() == 2015) .map(s -> s.getScore()) .max();
  183. 183. STREAM API LOS STREAMS SON OBJETOS int highScore = students.stream() .filter(s -> s.gradutationYear() == 2015) .map(s -> s.getScore()) .max(); regresa un int
  184. 184. STREAM API LOS STREAMS SON OBJETOS int highScore = students.stream() .filter(s -> s.gradutationYear() == 2015) .map(s -> s.getScore()) .max(); regresa un int map debe envolver el int 
 en un Integer
  185. 185. STREAM API LOS STREAMS SON OBJETOS int highScore = students.stream() .filter(s -> s.gradutationYear() == 2015) .map(s -> s.getScore()) .max(); regresa un int map debe envolver el int 
 en un Integer max extrae cada Integer
 para obtener el mayor
  186. 186. STREAM API STREAMS DE PRIMITIVOS int highScore = students.stream() .filter(s -> s.gradutationYear() == 2015) .mapToInt(s -> s.getScore()) .max();
  187. 187. STREAM API STREAMS DE PRIMITIVOS int highScore = students.stream() .filter(s -> s.gradutationYear() == 2015) .mapToInt(s -> s.getScore()) .max(); mapToInt produce un stream de int, 
 así ya no hay boxing o unboxing
  188. 188. STREAM API STREAMS DE PRIMITIVOS int highScore = students.stream() .filter(s -> s.gradutationYear() == 2015) .mapToInt(s -> s.getScore()) .max(); mapToInt produce un stream de int, 
 así ya no hay boxing o unboxing ▸ Para mejorar la eficiencia existen tres tipos de stream primitivos
  189. 189. STREAM API STREAMS DE PRIMITIVOS int highScore = students.stream() .filter(s -> s.gradutationYear() == 2015) .mapToInt(s -> s.getScore()) .max(); mapToInt produce un stream de int, 
 así ya no hay boxing o unboxing ▸ Para mejorar la eficiencia existen tres tipos de stream primitivos ▸ IntStream, DoubleStream y LongStream
  190. 190. STREAM API STREAMS DE PRIMITIVOS int highScore = students.stream() .filter(s -> s.gradutationYear() == 2015) .mapToInt(s -> s.getScore()) .max(); mapToInt produce un stream de int, 
 así ya no hay boxing o unboxing ▸ Para mejorar la eficiencia existen tres tipos de stream primitivos ▸ IntStream, DoubleStream y LongStream ▸ Usar metodos como mapToInt(), mapToDouble() y mapToLong()
  191. 191. STREAM API OPERACIONES INTERMEDIAS - FUENTES ▸ generate(Supplier<T> s) ▸ Genera una secuencia infinita y desordenada de los valores producidos por Supplier ▸ of(T t) of(T... values) ▸ Genera un stream con un solo elemento T o una secuencia de valores T ▸ iterate(T seed, UnaryOperator<T> f) ▸ Genera una secuencia infinita producida de aplicar iterativamente la función f(seed), f(f(seed)),…
  192. 192. STREAM API OPERACIONES INTERMEDIAS - FILTRADO ▸ filter(Predicate<? super T> predicate) ▸ Regresa un stream que contiene sólo los elementos que corresponden tras aplicar el Predicate proporcionado ▸ limit(long maxSize) ▸ Regresa un stream truncado con a lo mucho maxSize elementos ▸ skip(long n) ▸ Regresa un stream con los elementos sobrantes tras descartar los primeros n elementos
  193. 193. STREAM API OPERACIONES INTERMEDIAS - ORDEN ▸ distinct() ▸ Regresa un stream que contiene sólo los elementos que son diferentes aplicando un Object.equals(Object) ▸ sorted() ▸ Regresa un stream ordenado según el orden natural de los objetos contenidos ▸ sorted(Comparator<? super T> comparator) ▸ Regresa un stream ordenado según el Comparator proporcionado
  194. 194. STREAM API OPERACIONES INTERMEDIAS - MAPEO ▸ map(Function<? super T,? extends R> mapper) ▸ Regresa un stream que contiene los resultados de aplicar la función proporcionada a cada elemento ▸ flatMap(Function<? super T,? extends Stream<? extends R>> mapper) ▸ Regresa un stream que reemplaza los elementos del stream actual por los elementos del stream mapeado ▸ orders.flatMap(order -> order.getLineItems().stream())
  195. 195. STREAM API OPERACIONES INTERMEDIAS - MAPEO Map FlatMap
  196. 196. STREAM API OPERACIONES TERMINALES - MATCH ▸ allMatch(Predicate<? super T> predicate) ▸ true si todos los elementos pasan la prueba del Predicate ▸ anyMatch(Predicate<? super T> predicate) ▸ true si alguno de los elementos pasa la prueba del Predicate ▸ noneMatch(Predicate<? super T> predicate) ▸ true si ninguno de los elementos pasa la prueba del Predicate
  197. 197. STREAM API OPERACIONES TERMINALES - NUMÉRICOS ▸ max(Comparator<? super T> comparator) ▸ Optional del elemento mayor según comparator ▸ min(Comparator<? super T> comparator) ▸ Optional del elemento menor según comparator ▸ count() ▸ Cantidad de elementos en el stream
  198. 198. STREAM API OPERACIONES TERMINALES - MÁS NUMÉRICOS ▸ Para los Streams de Primitivos IntStream, LongStream, DoubleStream ▸ average() ▸ Obtiene el promedio de los elementos ▸ Regresa un Optional pues la lista puede estar vacía ▸ sum() ▸ Obtiene la suma de los elementos
  199. 199. STREAM API OPERACIONES TERMINALES - REDUCTORES ▸ reduce(BinaryOperator<T> accumulator) ▸ Reducción de elementos de este stream usando una función de acumulación asociativa ▸ Este acumulador toma un resultado parcial y el siguiente elemento y regresa un resultado parcial ▸ Regresa un Optional
  200. 200. STREAM API REDUCTORES ▸ Encontrar la longitud de la línea mas larga de un archivo Path input = Paths.get("lines.txt"); int longestLineLength = Files.lines(input) .mapToInt(String::length) .max() .getAsInt();
  201. 201. STREAM API REDUCTORES ▸ Encontrar la longitud de la línea mas larga de un archivo
  202. 202. STREAM API REDUCTORES ▸ Encontrar la longitud de la línea mas larga de un archivo String longest = Files.lines(input) .sort((x, y) -> y.length() - x.length()) .findFirst() .get();
  203. 203. STREAM API REDUCTORES ▸ Encontrar la longitud de la línea mas larga de un archivo String longest = Files.lines(input) .sort((x, y) -> y.length() - x.length()) .findFirst() .get(); ¿Y si el archivo es muy grande?
  204. 204. STREAM API REDUCTORES - ALTERNATIVAS ▸ Usar un while y una variable que contenga el resultado ▸ simple, pero no es thread safe ▸ Usar recursión ▸ No tiene una variable mutable, por lo que es thread safe ▸ En un archivo largo podemos tener un stack overflow ▸ Usar reduce(BinaryOperator<T> accumulator) ▸ El accumulator obtiene un resultado parcial y el siguiente elemento ▸ Como con recursión, pero sin el stack overflow
  205. 205. STREAM API REDUCTORES ▸ Encontrar la línea mas larga de un archivo String longestLine = Files.lines(input) .reduce((x, y) -> { if (x.length() > y.length()) return x; return y; }) .get();
  206. 206. STREAM API REDUCTORES ▸ Encontrar la línea mas larga de un archivo String longestLine = Files.lines(input) .reduce((x, y) -> { if (x.length() > y.length()) return x; return y; }) .get(); La x mantiene el estado, 
 en este caso guarda la linea más larga
  207. 207. STREAM API OPERACIONES TERMINALES - COLECTORES ▸ collect(Collector<? super T,A,R> collector) ▸ Realiza una reducción mutable de los elementos del stream ▸ El Contenedor del resultado puede ser un List, Map, String, etc ▸ toArray() ▸ Regresa un Array con los elementos del Stream
  208. 208. STREAM API COLLECTORS ▸ La clase Collectors implementa muchos colectores como: ▸ toList() ▸ List<String> list = people.stream()
 .map(Person::getName)
 .collect(Collectors.toList()); ▸ toCollection(Supplier<C> collectionFactory) ▸ Set<String> set = people.stream()
 .map(Person::getName).collect(
 Collectors.toCollection(TreeSet::new));
  209. 209. STREAM API COLLECTORS - A UN MAPA ▸ toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper) ▸ Map<String, Student> studentIdToStudent 
 students.stream()
 .collect(toMap(Student::getId,
 Functions.identity()); ▸ toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction) ▸ Map<String, String> phoneBook = 
 people.stream().collect(toMap(Person::getName, 
 Person::getAddress, (s, a) -> s + ", " + a)); ▸ Para mapas concurrentes usar toConcurrentMap(…)
  210. 210. STREAM API COLLECTORS - AGRUPACIONES ▸ groupingBy(Function<? super T,? extends K> classifier) ▸ Map<Department, List<Employee>> byDept = employees.stream().collect(
 Collectors.groupingBy(Employee::getDepartment)); ▸ groupingBy(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream) ▸ Map<City, Set<String>> namesByCity = people.stream().collect(groupingBy(
 Person::getCity, mapping(Person::getLastName, toSet()))); ▸ Para agrupaciones concurrentes usar groupingByConcurrent(…)
  211. 211. STREAM API COLLECTORS - UNIENDO CADENAS ▸ Otra forma de coleccionar resultados es concatenarlos en cadenas ▸ joining() ▸ joining(CharSequence delimiter) ▸ joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) String joined = things.stream()
 .map(Object::toString)
 .collect(Collectors.joining(", "));
  212. 212. STREAM API OPERACIONES TERMINALES - ITERACIÓN ▸ Stream cuenta con métodos para iterar el stream resultante, pero dependiendo de lo que se esté haciendo muy probablemente alguno de los colectores anteriores lo pueda realizar ▸ forEach(Consumer<? super T> action) ▸ Realiza la action para cada elemento en el stream ▸ forEachOrdered(Consumer<? super T> action) ▸ Realiza la action para cada elemento en el stream garantizando el orden si se ejecuta en paralelo
  213. 213. STREAM API PROCESAMIENTO EN PARALELO ▸ Una "ventaja" del uso de streams es su facilidad para convertirlas a procesos paralelos ▸ Para convertir un stream a procesamiento en paralelo sólo hay que agregar parallel() al pipeline o usar parallelStream() al generar el stream ▸ Basado en el framework Fork-Join ▸ Considerarlo si, y sólo si, las operaciones intermedias o terminales a realizar son computacionalmente pesadas y se tienen miles de elementos
  214. 214. GRACIAS EN RESUMEN ▸ En Java 8 contamos con nuevas herramientas ▸ Lambdas - Funciones independientes para realizar tareas muy específicas ▸ Optional - Forma de manejar la incertidumbre ▸ Streams - Forma de procesar colecciones o secuencias de valores

×