Workshop: Lambdas y Stream API en Java 8

214
LAMBDAS & STREAM API JAVA 8 @SuperSerch

Transcript of Workshop: Lambdas y Stream API en Java 8

Page 1: Workshop: Lambdas y Stream API en Java 8

LAMBDAS & STREAM APIJAVA 8

@SuperSerch

Page 2: Workshop: Lambdas y Stream API en Java 8

INTRODUCCIÓN

¿POR QUÉ TENER LAMBDAS Y STREAMS?

▸ Facilitar la programación concurrente

▸ Reducir los errores al programar iteraciones de colecciones

Page 3: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

PERSON

class Person { int getAge(); Sex getSex(); PhoneNumber getPhoneNumber(); EmailAddr getEmailAddr(); PostalAddr getPostalAddr(); ... }

enum Sex { FEMALE, MALE }

Page 4: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

ROBOCALL - PERSONAS EN EDAD DE CONDUCIR

class MyApplication {

List<Person> list = ...

void robocallEligibleDrivers() { ... }

... }

Page 5: Workshop: Lambdas y Stream API en Java 8

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); } } }

Page 6: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

ROBOCALL - PERSONAS EN EDAD DE VOTAR

Page 7: Workshop: Lambdas y Stream API en Java 8

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); } } }

Page 8: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

ROBOCALL - PERSONAS EN EDAD DE BEBER

Page 9: Workshop: Lambdas y Stream API en Java 8

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); } } }

Page 10: Workshop: Lambdas y Stream API en Java 8

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

Page 11: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

SOLUCIÓN PARAMETRIZAR!

Page 12: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

SOLUCIÓN PARAMETRIZAR!

void robocallOlderThan(int age) { for (Person p : list) { if (p.getAge()>=age){ Phonenumber num = p.getPhoneNumber(); robocall(num); } } }

Page 13: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

USANDO PARÁMETROS

void robocallEligibleDrivers() { robocallOlderThan(16); } void robocallEligibleVoters() { robocallOlderThan(18); } void robocallEligibleDrinkers() { robocallOlderThan(21); }

Page 14: Workshop: Lambdas y Stream API en Java 8

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

Page 15: Workshop: Lambdas y Stream API en Java 8

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); } } }

Page 16: Workshop: Lambdas y Stream API en Java 8

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); }

Page 17: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

UN REQUERIMIENTO MÁS

▸ Enviar publicidad a obligados a cumplir servicio militar

▸ con edades entre 18 y 26

▸ sólo hombres

Page 18: Workshop: Lambdas y Stream API en Java 8

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); }

Page 19: Workshop: Lambdas y Stream API en Java 8

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); } } }

Page 20: Workshop: Lambdas y Stream API en Java 8

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); }

Page 21: Workshop: Lambdas y Stream API en Java 8

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); }

Page 22: Workshop: Lambdas y Stream API en Java 8

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); } } }

Page 23: Workshop: Lambdas y Stream API en Java 8

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); } } }

Page 24: Workshop: Lambdas y Stream API en Java 8

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

Page 25: Workshop: Lambdas y Stream API en Java 8

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); } } }

Page 26: Workshop: Lambdas y Stream API en Java 8

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); }

Page 27: Workshop: Lambdas y Stream API en Java 8

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?

Page 28: Workshop: Lambdas y Stream API en Java 8

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); } } }

Page 29: Workshop: Lambdas y Stream API en Java 8

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); }

Page 30: Workshop: Lambdas y Stream API en Java 8

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

Page 31: Workshop: Lambdas y Stream API en Java 8

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?

Page 32: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

LO QUE EL CALLER QUIERE

void robocallSelectiveService() { robocallMatchingPersons(*******) }

Page 33: Workshop: Lambdas y Stream API en Java 8

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

Page 34: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

LO QUE LA BIBLIOTECA QUIEREvoid robocallMatchingPersons(********) { for (Person p : list) { if (***) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } }

Page 35: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

LO QUE LA BIBLIOTECA QUIEREvoid robocallMatchingPersons(********) { for (Person p : list) { if (***) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } }

Page 36: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

LO QUE LA BIBLIOTECA QUIEREvoid robocallMatchingPersons(********) { for (Person p : list) { if (***) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } }

ES UNA FUNCIÓN!

Page 37: Workshop: Lambdas y Stream API en Java 8

CASO DE EJEMPLO

LO QUE LA BIBLIOTECA QUIEREvoid 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

Page 38: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

¿QUÉ ES UNA EXPRESIÓN LAMBDA?

Page 39: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

¿QUÉ ES UNA EXPRESIÓN LAMBDA?

▸ Forma matemática que define la transformación de un valor

Page 40: Workshop: Lambdas y Stream API en Java 8

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

Page 41: Workshop: Lambdas y Stream API en Java 8

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

Page 42: Workshop: Lambdas y Stream API en Java 8

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

Page 43: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

PROPÓSITO DE LAS EXPRESIONES LAMBDA

Page 44: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

PROPÓSITO DE LAS EXPRESIONES LAMBDA

▸ Proveen una manera sencilla para distribuir procesamiento específico

Page 45: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

PROPÓSITO DE LAS EXPRESIONES LAMBDA

▸ Proveen una manera sencilla para distribuir procesamiento específico

▸ Útiles para procesar colecciones

Page 46: Workshop: Lambdas y Stream API en Java 8

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

Page 47: Workshop: Lambdas y Stream API en Java 8

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}

Page 48: Workshop: Lambdas y Stream API en Java 8

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()); } });

Page 49: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

LAMBDAS

Page 50: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

LAMBDAS

▸ Bloque de código

Page 51: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

LAMBDAS

▸ Bloque de código

▸ Se basan en Target Typing (Según el contexto se determina el tipo de la Lambda)

Page 52: Workshop: Lambdas y Stream API en Java 8

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:

Page 53: Workshop: Lambdas y Stream API en Java 8

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

Page 54: Workshop: Lambdas y Stream API en Java 8

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

Page 55: Workshop: Lambdas y Stream API en Java 8

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

Page 56: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

FUNCTIONAL INTERFACE

Page 57: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

FUNCTIONAL INTERFACE

▸ Interfaces que tienen sólo un método abstracto.

Page 58: Workshop: Lambdas y Stream API en Java 8

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

Page 59: Workshop: Lambdas y Stream API en Java 8

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

Page 60: Workshop: Lambdas y Stream API en Java 8

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

Page 61: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONAL

interface Runnable { void run(); }

Page 62: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONAL

interface Runnable { void run(); } ✔

Page 63: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONAL

interface NonFunc { boolean equals(Object obj); }

Page 64: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONAL

interface NonFunc { boolean equals(Object obj); } ✗

Page 65: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONAL

interface Func extends NonFunc { int compare(String o1, String o2); }

Page 66: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONAL

interface Func extends NonFunc { int compare(String o1, String o2); } ✔

Page 67: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONAL

interface Comparator<T> { boolean equals(Object obj); int compare(T o1, T o2); }

Page 68: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONAL

interface Comparator<T> { boolean equals(Object obj); int compare(T o1, T o2); }

Page 69: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONAL

interface Foo { int m(); Object clone(); }

Page 70: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONAL

interface Foo { int m(); Object clone(); }

Page 71: Workshop: Lambdas y Stream API en Java 8

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 {}

Page 72: Workshop: Lambdas y Stream API en Java 8

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 {}

Page 73: Workshop: Lambdas y Stream API en Java 8

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 {}

Page 74: Workshop: Lambdas y Stream API en Java 8

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 {}

Page 75: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONALinterface 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> {}

Page 76: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONALinterface 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> {}

Page 77: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONALinterface 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> {}

Page 78: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONALinterface 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> {}

Page 79: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONAL

interface X { long m(); }

interface Y { int m(); }

interface Z extends X, Y {}

Page 80: Workshop: Lambdas y Stream API en Java 8

FUNCTIONAL INTERFACE

RECONOCIENDO UNA INTERFACE FUNCIONAL

interface X { long m(); }

interface Y { int m(); }

interface Z extends X, Y {}

Page 81: Workshop: Lambdas y Stream API en Java 8

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> {}

Page 82: Workshop: Lambdas y Stream API en Java 8

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> {}

Page 83: Workshop: Lambdas y Stream API en Java 8

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> {}

Page 84: Workshop: Lambdas y Stream API en Java 8

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> {}

✗✔

Page 85: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

SINTAXIS DE UNA LAMBDA

(parameters) -> expresion

(parameters) -> { statements; } //return necesario

Page 86: Workshop: Lambdas y Stream API en Java 8

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); } });

Page 87: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

EJEMPLO - COMPARATOR

List<Animal> farm = loadAnimals(); Collections.sort(farm, (Animal a1, Animal a2) -> a1.name.compareTo(a2.name));

Page 88: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

EJEMPLO - COMPARATOR

List<Animal> farm = loadAnimals(); Collections.sort(farm, (Animal a1, Animal a2) -> a1.name.compareTo(a2.name));

Page 89: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

EJEMPLO - COMPARATOR

List<Animal> farm = loadAnimals(); Collections.sort(farm,

(a1, a2) -> a1.name.compareTo(a2.name));

Page 90: Workshop: Lambdas y Stream API en Java 8

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; }

Page 91: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

¿QUÉ ES UNA LAMBDA?

Page 92: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

¿QUÉ ES UNA LAMBDA?

▸ instancias especiales de "objetos"

Page 93: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

¿QUÉ ES UNA LAMBDA?

▸ instancias especiales de "objetos"

▸ con dependencias autocontenidas (capturadas)

Page 94: Workshop: Lambdas y Stream API en Java 8

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

Page 95: Workshop: Lambdas y Stream API en Java 8

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

Page 96: Workshop: Lambdas y Stream API en Java 8

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)

Page 97: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

INTERFACES FUNCIONALES EN JDK 8

Page 98: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

INTERFACES FUNCIONALES EN JDK 8

▸ Supplier<T>

Page 99: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

INTERFACES FUNCIONALES EN JDK 8

▸ Supplier<T>

▸ Consumer<T>

Page 100: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

INTERFACES FUNCIONALES EN JDK 8

▸ Supplier<T>

▸ Consumer<T>

▸ Predicate<T>

Page 101: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

INTERFACES FUNCIONALES EN JDK 8

▸ Supplier<T>

▸ Consumer<T>

▸ Predicate<T>

▸ Function<T,R>

Page 102: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

INTERFACES FUNCIONALES EN JDK 8

▸ Supplier<T>

▸ Consumer<T>

▸ Predicate<T>

▸ Function<T,R>

▸ UnaryOperator<T>

Page 103: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

INTERFACES FUNCIONALES EN JDK 8

▸ Supplier<T>

▸ Consumer<T>

▸ Predicate<T>

▸ Function<T,R>

▸ UnaryOperator<T>

▸ BinaryOperator<T>

Page 104: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

INTERFACES FUNCIONALES EN JDK 8

▸ Supplier<T>

▸ Consumer<T>

▸ Predicate<T>

▸ Function<T,R>

▸ UnaryOperator<T>

▸ BinaryOperator<T>jav

a.util

.funct

ion

Page 105: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

Supplier<T>

Page 106: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

Supplier<T>▸ Representa a un proveedor de objetos tipo T

Page 107: Workshop: Lambdas y Stream API en Java 8

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

Page 108: Workshop: Lambdas y Stream API en Java 8

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()

Page 109: Workshop: Lambdas y Stream API en Java 8

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()); }

Page 110: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

Consumer<T>

Page 111: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

Consumer<T>▸ Representa una operación que acepta un único parámetro de

tipo T

Page 112: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

Consumer<T>▸ Representa una operación que acepta un único parámetro de

tipo T

▸ No regresa ningún resultado

Page 113: Workshop: Lambdas y Stream API en Java 8

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

Page 114: Workshop: Lambdas y Stream API en Java 8

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)

Page 115: Workshop: Lambdas y Stream API en Java 8

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));

Page 116: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

Predicate<T>

Page 117: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

Predicate<T>▸ Representa un predicado booleano de un argumento

Page 118: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

Predicate<T>▸ Representa un predicado booleano de un argumento

▸ Su método funcional es Predicate.test(Object)

Page 119: Workshop: Lambdas y Stream API en Java 8

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);

Page 120: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

Function<T,R>

Page 121: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

Function<T,R>▸ Representa una función de transformación de T a R

Page 122: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

Function<T,R>▸ Representa una función de transformación de T a R

▸ Regresa un objeto de tipo R

Page 123: Workshop: Lambdas y Stream API en Java 8

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)

Page 124: Workshop: Lambdas y Stream API en Java 8

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());

Page 125: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

UnaryOperator<T>

Page 126: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

UnaryOperator<T>▸ Representa una función de transformación de T a T

Page 127: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

UnaryOperator<T>▸ Representa una función de transformación de T a T

▸ Su método funcional es UnaryOperator.apply(Object)

Page 128: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

BinaryOperator<T>

Page 129: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

BinaryOperator<T>▸ Representa una función de Transformación de T, T a T

Page 130: Workshop: Lambdas y Stream API en Java 8

LAMBDAS

BinaryOperator<T>▸ Representa una función de Transformación de T, T a T

▸ Su método funcional es BinaryOperator.apply(Object, Object)

Page 131: Workshop: Lambdas y Stream API en Java 8

METHOD REFERENCES

METHOD REFERENCES

Consumer<String> consumer = s -> System.out.println(s);

Consumer<String> consumer = System.out::println;

Page 132: Workshop: Lambdas y Stream API en Java 8

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;

Page 133: Workshop: Lambdas y Stream API en Java 8

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;

Page 134: Workshop: Lambdas y Stream API en Java 8

METHOD REFERENCES

TIPOS DE METHOD REFERENCES

Page 135: Workshop: Lambdas y Stream API en Java 8

METHOD REFERENCES

TIPOS DE METHOD REFERENCES▸ Referencia a un método estático - ContainingClass::staticMethodName

Page 136: Workshop: Lambdas y Stream API en Java 8

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

Page 137: Workshop: Lambdas y Stream API en Java 8

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

Page 138: Workshop: Lambdas y Stream API en Java 8

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

Page 139: Workshop: Lambdas y Stream API en Java 8

OPTIONAL

Optional

Page 140: Workshop: Lambdas y Stream API en Java 8

OPTIONAL

Optional▸ Contenedor de un objeto que puede o no ser null

Page 141: Workshop: Lambdas y Stream API en Java 8

OPTIONAL

Optional▸ Contenedor de un objeto que puede o no ser null

▸ Si contiene un valor, isPresent() regresa true y get() el valor

Page 142: Workshop: Lambdas y Stream API en Java 8

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)

Page 143: Workshop: Lambdas y Stream API en Java 8

STREAM API

CASO DE EJEMPLO: CALCULAR EL PROMEDIO DE EDAD DE LOS ELEGIBLES A BEBER

Page 144: Workshop: Lambdas y Stream API en Java 8

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; }

Page 145: Workshop: Lambdas y Stream API en Java 8

STREAM API

APLICANDO STREAMS

Page 146: Workshop: Lambdas y Stream API en Java 8

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); }

Page 147: Workshop: Lambdas y Stream API en Java 8

STREAM API

STREAM API

Page 148: Workshop: Lambdas y Stream API en Java 8

STREAM API

STREAM API

▸ Diseñado para trabajar principalmente con colecciones

Page 149: Workshop: Lambdas y Stream API en Java 8

STREAM API

STREAM API

▸ Diseñado para trabajar principalmente con colecciones

▸ Provee de una manera "declarativa" de procesar una colección

Page 150: Workshop: Lambdas y Stream API en Java 8

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

Page 151: Workshop: Lambdas y Stream API en Java 8

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

Page 152: Workshop: Lambdas y Stream API en Java 8

STREAM API

¿QUÉ ES UN STREAM?

Page 153: Workshop: Lambdas y Stream API en Java 8

STREAM API

¿QUÉ ES UN STREAM?

▸ Secuencia de elementos

Page 154: Workshop: Lambdas y Stream API en Java 8

STREAM API

¿QUÉ ES UN STREAM?

▸ Secuencia de elementos

▸ No almacena valores, los genera bajo demanda

Page 155: Workshop: Lambdas y Stream API en Java 8

STREAM API

¿QUÉ ES UN STREAM?

▸ Secuencia de elementos

▸ No almacena valores, los genera bajo demanda

▸ Fuente de datos

Page 156: Workshop: Lambdas y Stream API en Java 8

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

Page 157: Workshop: Lambdas y Stream API en Java 8

STREAM API

¿QUÉ ES UN STREAM? (2)

Page 158: Workshop: Lambdas y Stream API en Java 8

STREAM API

¿QUÉ ES UN STREAM? (2)

▸ Operaciones de Agregación

Page 159: Workshop: Lambdas y Stream API en Java 8

STREAM API

¿QUÉ ES UN STREAM? (2)

▸ Operaciones de Agregación

▸ Operaciones estilo base de datos como: filter, map, reduce, findFirst, allMatch, sorted, …

Page 160: Workshop: Lambdas y Stream API en Java 8

STREAM API

¿QUÉ ES UN STREAM? (2)

▸ Operaciones de Agregación

▸ Operaciones estilo base de datos como: filter, map, reduce, findFirst, allMatch, sorted, …

▸ Encadenamiento

Page 161: Workshop: Lambdas y Stream API en Java 8

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

Page 162: Workshop: Lambdas y Stream API en Java 8

STREAM API

¿QUÉ ES UN STREAM? (3)

Page 163: Workshop: Lambdas y Stream API en Java 8

STREAM API

¿QUÉ ES UN STREAM? (3)

▸ Iteración Interna

Page 164: Workshop: Lambdas y Stream API en Java 8

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

Page 165: Workshop: Lambdas y Stream API en Java 8

STREAM API

STREM VS COLLECTION

Page 166: Workshop: Lambdas y Stream API en Java 8

STREAM API

STREM VS COLLECTION

▸ Sin Almacenamiento

Page 167: Workshop: Lambdas y Stream API en Java 8

STREAM API

STREM VS COLLECTION

▸ Sin Almacenamiento

▸ Funcionales

Page 168: Workshop: Lambdas y Stream API en Java 8

STREAM API

STREM VS COLLECTION

▸ Sin Almacenamiento

▸ Funcionales

▸ Flojas

Page 169: Workshop: Lambdas y Stream API en Java 8

STREAM API

STREM VS COLLECTION

▸ Sin Almacenamiento

▸ Funcionales

▸ Flojas

▸ Posiblemente Ilimitadas

Page 170: Workshop: Lambdas y Stream API en Java 8

STREAM API

STREM VS COLLECTION

▸ Sin Almacenamiento

▸ Funcionales

▸ Flojas

▸ Posiblemente Ilimitadas

▸ limit(n) findFirst()

Page 171: Workshop: Lambdas y Stream API en Java 8

STREAM API

STREM VS COLLECTION

▸ Sin Almacenamiento

▸ Funcionales

▸ Flojas

▸ Posiblemente Ilimitadas

▸ limit(n) findFirst()

▸ Consumibles

Page 172: Workshop: Lambdas y Stream API en Java 8

STREAM API

PIPELINE

Page 173: Workshop: Lambdas y Stream API en Java 8

STREAM API

PIPELINE

▸ Fuente de datos

Page 174: Workshop: Lambdas y Stream API en Java 8

STREAM API

PIPELINE

▸ Fuente de datos

▸ una o varias operaciones Intermedias

Page 175: Workshop: Lambdas y Stream API en Java 8

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

Page 176: Workshop: Lambdas y Stream API en Java 8

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

Page 177: Workshop: Lambdas y Stream API en Java 8

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

Page 178: Workshop: Lambdas y Stream API en Java 8

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

Page 179: Workshop: Lambdas y Stream API en Java 8

STREAM API

APLICANDO STREAMS

Page 180: Workshop: Lambdas y Stream API en Java 8

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); }

Page 181: Workshop: Lambdas y Stream API en Java 8

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

Page 182: Workshop: Lambdas y Stream API en Java 8

STREAM API

LOS STREAMS SON OBJETOS

int highScore = students.stream() .filter(s -> s.gradutationYear() == 2015) .map(s -> s.getScore()) .max();

Page 183: Workshop: Lambdas y Stream API en Java 8

STREAM API

LOS STREAMS SON OBJETOS

int highScore = students.stream() .filter(s -> s.gradutationYear() == 2015) .map(s -> s.getScore()) .max();

regresa un int

Page 184: Workshop: Lambdas y Stream API en Java 8

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

Page 185: Workshop: Lambdas y Stream API en Java 8

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 Integerpara obtener el mayor

Page 186: Workshop: Lambdas y Stream API en Java 8

STREAM API

STREAMS DE PRIMITIVOS

int highScore = students.stream() .filter(s -> s.gradutationYear() == 2015) .mapToInt(s -> s.getScore()) .max();

Page 187: Workshop: Lambdas y Stream API en Java 8

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

Page 188: Workshop: Lambdas y Stream API en Java 8

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

Page 189: Workshop: Lambdas y Stream API en Java 8

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

Page 190: Workshop: Lambdas y Stream API en Java 8

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()

Page 191: Workshop: Lambdas y Stream API en Java 8

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)),…

Page 192: Workshop: Lambdas y Stream API en Java 8

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

Page 193: Workshop: Lambdas y Stream API en Java 8

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

Page 194: Workshop: Lambdas y Stream API en Java 8

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())

Page 195: Workshop: Lambdas y Stream API en Java 8

STREAM API

OPERACIONES INTERMEDIAS - MAPEO

Map

FlatMap

Page 196: Workshop: Lambdas y Stream API en Java 8

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

Page 197: Workshop: Lambdas y Stream API en Java 8

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

Page 198: Workshop: Lambdas y Stream API en Java 8

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

Page 199: Workshop: Lambdas y Stream API en Java 8

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

Page 200: Workshop: Lambdas y Stream API en Java 8

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();

Page 201: Workshop: Lambdas y Stream API en Java 8

STREAM API

REDUCTORES

▸ Encontrar la longitud de la línea mas larga de un archivo

Page 202: Workshop: Lambdas y Stream API en Java 8

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();

Page 203: Workshop: Lambdas y Stream API en Java 8

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

archiv

o es

muy gr

ande?

Page 204: Workshop: Lambdas y Stream API en Java 8

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

Page 205: Workshop: Lambdas y Stream API en Java 8

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();

Page 206: Workshop: Lambdas y Stream API en Java 8

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

Page 207: Workshop: Lambdas y Stream API en Java 8

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

Page 208: Workshop: Lambdas y Stream API en Java 8

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));

Page 209: Workshop: Lambdas y Stream API en Java 8

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(…)

Page 210: Workshop: Lambdas y Stream API en Java 8

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(…)

Page 211: Workshop: Lambdas y Stream API en Java 8

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(", "));

Page 212: Workshop: Lambdas y Stream API en Java 8

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

Page 213: Workshop: Lambdas y Stream API en Java 8

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

Page 214: Workshop: Lambdas y Stream API en Java 8

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