Download - Lambdas y API Stream #PerúJUG #Java20
![Page 1: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/1.jpg)
Perú JUGDIC-2015
Alexis López@aa_lopez
![Page 2: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/2.jpg)
Agenda
Expresiones Lambda
Stream API
Taller Práctico
11
22
33
![Page 3: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/3.jpg)
Expresiones LambdaFunciones como valores/parámetros
<<interface>>ApplePredicate
+test(Apple):boolean
AppleGreenColorPredicate AppleRedColorPredicate
AppleHeavyWeightPredicateAppleRedAndHeavyPredicate
+test(Apple):boolean +test(Apple):boolean
+test(Apple):boolean +test(Apple):boolean
Apple
+getWeight():double+getColor():String
![Page 4: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/4.jpg)
Expresiones LambdaFunciones como valores/parámetros
public class AppleHeavyWeightPredicate implements ApplePredicate{public boolean test(Apple apple){
return apple.getWeight() > 150;}
}
public class AppleGreenColorPredicate implements ApplePredicate{public boolean test(Apple apple){
return "green".equals(apple.getColor());}
}
...
Código tomado del libro Java 8 in Action
![Page 5: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/5.jpg)
Expresiones LambdaFunciones como valores/parámetros
…
public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p){List<Apple> result = new ArrayList<>();for(Apple apple: inventory){
if(p.test(apple)){result.add(apple);
}}return result;
}
...
Código tomado del libro Java 8 in Action
Nuestro predicado encapsulala condición
![Page 6: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/6.jpg)
Expresiones LambdaFunciones como valores/parámetros
…
List<Apple> inventory = ...//Separar manzanas por colorList<Apple> greenApples = filterApples(inventory, new
AppleGreenColorPredicate());
//Separar manzanas por pesoList<Apple> heavyApples = filterApples(inventory, new
AppleHeavyWeightPredicate());
...
Código tomado del libro Java 8 in Action
public boolean test(Apple apple){return apple.getWeight() > 150;
}
Necesitaríamos muchas clases...
![Page 7: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/7.jpg)
Expresiones LambdaFunciones como valores/parámetros
…List<Apple> inventory = ...List<Apple> redApples = filterApples(inventory, new ApplePredicate() {
public boolean test(Apple apple){ return "red".equals(apple.getColor());}
});
List<Apple> greenApples = filterApples(inventory, new ApplePredicate() {
public boolean test(Apple apple){return "green".equals(apple.getColor());
}});
...
Código tomado del libro Java 8 in Action
Enredado, repetido...
![Page 8: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/8.jpg)
Expresiones LambdaFunciones como valores/parámetros
...List<Apple> inventory = …
List<Apple> redApples = filterApples(inventory, (Apple a) -> "red".equals(a.getColor());
List<Apple> greenApples = filterApples(inventory, (Apple a) -> "green".equals(a.getColor()));
...
Código tomado del libro Java 8 in Action
Parametrización de comportamiento
![Page 9: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/9.jpg)
Expresiones LambdaDefinición
Métodos anónimos, es decir, métodos sin nombre o clase.
Paquete java.util.function
Permite escribir código más claro que usar clases anónimas.
(parámetros) -> {cuerpo expresión lambda}
Operador lambda
![Page 10: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/10.jpg)
Expresiones LambdaDefinición
Ejemplos de expresiones lambda:(int a, int b) -> a + ba -> a + 1(int a, int b) -> { System.out.println(a + b); return a + b; }
• El cuerpo puede lanzar excepciones• Una sola línea no requiere llaves ni la sentencia return• Varias líneas requieren separador punto y coma (;)• Un solo parámetro no requiere paréntesis• Ningún parámetro requiere paréntesis vacíos
Parámetros CuerpoOperador lambda
![Page 11: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/11.jpg)
Expresiones LambdaDefiniciones – Interfaces Recargadas - Métodos por Defecto
Definidos e implementados en la Interface.
Implementación por defecto se usa solo cuando la clase implementadora no provee su propia implementación
Para quien invoca, es un método más de la Interface.
Especial cuidado cuando se implementen Interfaces con métodos por defecto iguales…
public interface MorningInterface { default void saludo(){ System.out.println("Buenos días"); }}
public interface AfternoonInterface { default void saludo(){ System.out.println("Buenas tardes"); }}
Interface List<T> {…
default void sort(Comparator<? super T> cmp){
Collections.sort(this, cmp); }
…}
![Page 12: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/12.jpg)
Expresiones LambdaDefiniciones – Interfaces Recargadas - Métodos por Defecto
En caso de conflictos, este es el orden en el que se selecciona el método por defecto:
1. Implementaciones en clases concretas2. Implementaciones en subinterfaces3. Explícitamente seleccionando el método usando: X.super.m(...)
Donde X es la interface y m es el método deseado
También debemos notar que, a partir de Java 8, además de métodos por defecto, las interfaces también pueden proveer implementación de métodos estáticos.
![Page 13: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/13.jpg)
Expresiones LambdaDefiniciones – Interfaces Recargadas - Métodos por Defecto
public class MultipleInheritance implements MorningInterface{ public static void main(String... args) { MultipleInheritance m = new MultipleInheritance();
m.saludo(); //Buenos días }}
![Page 14: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/14.jpg)
Expresiones LambdaDefiniciones – Interfaces Recargadas - Métodos por Defecto
public class MultipleInheritance implements MorningInterface, AfternoonInterface { public static void main(String... args) { MultipleInheritance m = new MultipleInheritance();
m.saludo(); //Saludo desde clase implementadora m.saludoMañanero(); //Buenos días m.saludoTarde(); //Buenas tardes }
@Override public void saludo() { System.out.println("Saludo desde clase implementadora"); }
public void saludoMañanero() { MorningInterface.super.saludo(); }
public void saludoTarde() { AfternoonInterface.super.saludo(); }}
En este caso es obligatorio implementar el método
En este caso es obligatorio implementar el método
![Page 15: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/15.jpg)
Expresiones LambdaDefiniciones – Interfaces Funcionales
SAM: Single Abstract Method.
Interface Funcional: Interface con un solo método abstracto (SAM) y diferente a los métodos de Object (toString, equals…).
@FunctionalInterfaceIndica al compilador que debe verificar si se trata de una interfase funcional.
@FunctionalInterfacepublic interface InterfaceEjemplo{ /** Imprime algo*/ void imprimir(); /** Método de Object, no cuenta contra SAM*/ boolean equals(Object obj);}
//Ejemplo de Interfases funcionales que ya conocemos:
Interface Runnable { void run(); }
Interface Comparator<T> { boolean compare(T x, T y);
}
Interface ActionListener { void actionPerformed(…); }
![Page 16: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/16.jpg)
Expresiones LambdaDefiniciones – Interface Funcional – 4 Grandes Grupos
@FunctionalInterfacepublic interface Supplier<T> {
T get();
//Otros métodos...}
@FunctionalInterfacepublic interface Function<T, R> {
R apply(T);
//Otros métodos...}
@FunctionalInterfacepublic interface Predicate<T> {
boolean test(T t);
//Otros métodos...}
@FunctionalInterfacepublic interface Consumer<T> {
void accept(T t);
//Otros métodos...}
Uso: Mapear de un valor a otro
Uso: Creación de objetosUso: Validación de criterios
Uso: Consumir métodos del parámetro. Tiene efectos secundarios
![Page 17: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/17.jpg)
Expresiones LambdaDefiniciones – Inferencia de tipos
//Comparator usando clases anónimas...
Comparator<String> c = new Comparator<String>() {public int compare(String x, String y) {
return x.length() - y.length();}
};
//Comparator usando Lambdas...
Comparator<String> c = (x, y) -> x.length() - y.length();
Contexto de asignaciónContexto de asignación
![Page 18: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/18.jpg)
Expresiones LambdaDefiniciones – Inferencia de tipos
//Comparator usando clases anónimas...
Comparator<String> c = new Comparator<String>() {public int compare(String x, String y) {
return x.length() - y.length();}
};
//Comparator usando Lambdas...
Comparator<String> c = (x, y) -> x.length() - y.length();
Contexto de asignaciónContexto de asignación
![Page 19: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/19.jpg)
Expresiones LambdaDefiniciones – Inferencia de tipos - Casos especiales
//Misma expresión lambda, diferentes interfaces funcionalesCallable<Integer> c = () -> 42;PrivilegedAction<Integer> p = () -> 42;
//void-compatibility ruleList<String> list = ...Predicate<String> p = s -> list.add(s);Consumer<String> c = s -> list.add(s);
Aunque el método abstracto de Consumerretorna void, no hay error de compilación
![Page 20: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/20.jpg)
Expresiones LambdaDefiniciones – Alcance
Efectivamente Constante: Variable o parámetro que solo es asignado una vez.
this hace referencia a la instancia de la clase sobre la cual se ha escrito la expresión Lambda.
void expire(File root, long before) {...root.listFiles(File p -> p.lastModified() <= before);...
//Esto causaría error de compilaciónbefore = 10000;}
class SessionManager {long before = ...;void expire(File root) {...
root.listFiles(File p -> checkExpiry(p.lastModified(), this.before));
}boolean checkExpiry(long time, long expiry) { ... }}
![Page 21: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/21.jpg)
Expresiones LambdaDefiniciones – Métodos de Referencia
Invocación de métodos por su nombre. Expresiones Lambda más compactas y fáciles de leer.
Solo para cuando la expresión lambda tiene una sola sentencia.
Existen 4 tipos:Métodos EstáticosMétodos de Instancia de un objetoMétodos de Instancia de algún tipoConstructores
//Uso para métodos estáticosClase::metodoEstatico//Uso para métodos de instancia de un objeto existenteObjeto::metodoDeInstancia//Uso para métodos de instancia de algún tipo de objetoTipo::metodoDeInstancia//Uso para constructoresClase::new
public class Person {
String name; LocalDate birthday; //gets…sets…
public static int compareByAge(Person a, Person b) { return a.birthday.compareTo(b.birthday); }}
![Page 22: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/22.jpg)
Expresiones LambdaDefiniciones – Métodos de Referencia::Métodos Estáticos
public class Testing{
public static void main(String… args){
Person[] personArray = new Person[1000];…//ingresar objetos tipo persona al arreglo...…//Ordenar el arreglo usando lambdasArrays.sort(personArray, (a, b) -> Person.compareByAge(a, b));
//Ordenar el arreglo usando métodos de referenciaArrays.sort(personArray, Person::compareByAge);
}}
![Page 23: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/23.jpg)
Expresiones LambdaDefiniciones – Métodos de Referencia::Métodos de Instancia de un objeto
public class ComparisonProvider { public int compareByName(Person a, Person b) { return a.getName().compareTo(b.getName());}}...public class Testing{
public static void main(String… args){
Person[] personArray = new Person[1000];//ingresar objetos tipo persona al arreglo...
ComparisonProvider myComparisonProvider = new ComparisonProvider();//Ordenar el arreglo usando lambdasArrays.sort(personArray, (a,b)->myComparisonProvider.compareByName(a, b));
//Ordenar el arreglo usando métodos de referenciaArrays.sort(personArray, myComparisonProvider::compareByName);
}}
![Page 24: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/24.jpg)
Expresiones LambdaDefiniciones – Métodos de Referencia::Métodos de Instancia de algún Tipo
public class Testing{
public static void main(String… args){
String[] stringArray = {"Zuñiga", "James", "Cuadrado", "John", "Armero", "Murillo", "Falcao", "Martínez"};
//Ordenar el arreglo usando lambdasArrays.sort(stringArray, (a, b) -> a.compareToIgnoreCase(b));
//Ordenar el arreglo usando métodos de referenciaArrays.sort(stringArray, String::compareToIgnoreCase);
}}
![Page 25: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/25.jpg)
Expresiones LambdaDefiniciones – Métodos de Referencia::Constructores
public class Testing{
public static void main(String… args){
//Crear una persona usando lambdasSupplier<Persona> s1 = () -> new Persona();
Persona p1 = s1.get();
//Crear una persona usando métodos de referenciaSupplier<Persona> s1 = Persona::new;Persona p1 = s1.get();
}}
![Page 26: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/26.jpg)
Expresiones LambdaDefiniciones – Métodos de Referencia::Constructores
public class Manzana{private int peso;public Manzana(int w){ peso = w;}
}…
//Crear una manzana usando lambdasFunction<Integer, Manzana> f1 = (w) -> new Manzana(w);Manzana m1 = f1.apply(100);
//Crear una manzana usando métodos de referenciaFunction<Integer, Manzana> f1 = Manzana::new;Manzana m1 = f1.apply(100);
...
![Page 27: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/27.jpg)
Expresiones LambdaDefiniciones – Expresiones Compuestas
Usar métodos por defecto para crear expresiones más complejas.
Predicate<T>Incluye métodos and, or, negate.
Function<T,R>Incluye métodos andThen y compose.
Comparator<T>Incluye métodos reversed, comparing, thenComparing.
//Creación de predicados complejosPredicate<String> p1 = s -> s.length() > 3;Predicate<String> p2 = s -> s.charAt(0) == 'A';Predicate<String> p3 = ...
//Precedencia de izquierda a derechaPredicate<String> p4 = p1.or(p2).and(p3).negate();
//Composición de funcionesFunction<String, Integer> f1 = String::length;Function<Integer, Integer> f2 = i -> i * 2;
//Primero aplica f1 y al resultado aplica f2Function<String, Integer> f3 = f1.andThen(f2);
//Composición de comparadoresComparator<String> c1 = (a,b) -> a.length() - b.length();Comparator<String> c2 = String::compareTo;
//Primero compare con c1 y si son iguales use c2Comparator<String> c3 = c1.thenComparing(c2);
![Page 28: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/28.jpg)
Stream APIDefiniciones - Stream
Secuencia de elementos de una fuente que soporta operaciones para el procesamiento de sus datos:
1. De forma declarativa usando expresiones lambda.2. Es posible el encadenamiento de varias operaciones haciendo al
código fácil de leer y con un objetivo claro.3. Operaciones se ejecutan de forma secuencial o paralela (Fork/Join)
Paquete java.util.stream
Interfase java.util.stream.Stream
Map
Reduce
Filter
![Page 29: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/29.jpg)
Stream APIDefiniciones - Stream
Un Stream está compuesto de tres (3) partes:
1. Una fuente de información2. Cero o más operaciones intermedias3. Una operación final: Produce un resultado o un efecto en los datos
List transacciones = ...int sum = transacciones.stream().
filter(t -> t.getProveedor().getCiudad().equals(“Cali”)). mapToInt(Transaccion::getPrecio). sum();
Fuente
Operaciones intermediasOperación terminal
![Page 30: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/30.jpg)
Stream APIDefiniciones - Stream
Propiedades de un Stream:
1. Operaciones intermedias retornan otro Stream = Encadenamiento de operaciones
2. Operaciones intermedias son encoladas hasta que una operación terminal sea invocada
3. Solo puede ser recorrido una vez (IllegalStateException)
4. Iteración interna = Iteración automática● Iteración secuencial o paralela transparante para el desarrollador ● Permite definir el “Qué quiero lograr” en vez del “Cómo lo quiero lograr”
5. Versiones “primitivas” evitan el Autoboxing y Unboxing ● DoubleStream● IntStream● LongStream
![Page 31: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/31.jpg)
Stream APIDefiniciones – Stream - Creación
Diferentes formas de obtener un Stream
1. Stream.of(T): Stream<T> -> Retorna un Stream ordenado y secuencial de los elementos pasados por parámetro
2. Stream.empty():Stream -> Retorna un Stream secuencial vacío.
3. Arrays.stream(T[]):Stream<T> -> Retorna un Stream secuencial del arreglo pasado por parámetro. Versión “primitiva” retorna: DoubleSTream, IntStream, LongStream.
4. Collection<E>.stream():Stream<E> -> Retorna un Stream secuencial de los elementos de la colección. Versión en paralelo: Collection<E>.parallelStream():Stream<E>
5. Stream.iterate(T, UnaryOperator<T>):Stream<T> -> Retorna un Stream infinito, ordenado y secuencial, a partir del valor inicial T y de aplicar la función UnaryOperator al valor inicial para obtener los demás elementos. Para limitar su tamaño, se puede usar el método +limit(long):Stream
6. Stream.generate(Supplier<T>):Stream<T> -> Retorna un Stream infinito, scuencial pero no ordenado, a partir de una expresión lambda que provee los elementos.
![Page 32: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/32.jpg)
Stream APIOperaciones sobre colecciones de datos - Filter
Para filtrar los elementos de un Stream podemos usar los siguientes métodos:
+filter(Predicate<T>):Stream<T> -> Retorna un Stream que contiene solo los elementos que cumplen con el predicado pasado por parámetro.
+distinct():Stream<T> -> Retorna un Stream sin elementos duplicados. Depende de la implementación de +equals(Object):boolean.
+limit(long):Stream<T> -> Retorna un Stream cuyo tamaño no es mayor al número pasado por parámetro. Los elementos son cortados hasta ese tamaño.
+skip(long):Stream<T> -> Retorna un Stream que descarta los primeros N elementos, donde N es el número pasado por parámetro. Si el Stream contiene menos elementos que N, entonces retorna un Stream vacío.
Map
Reduce
Filter
![Page 33: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/33.jpg)
Stream APIOperaciones sobre colecciones de datos - Map
Podemos transformar los elementos de un Stream al extraer información de éstos. Para lograrlo podemos usar alguno de los siguientes métodos:
+map(Function<T, R>): Stream<R> -> Retorna un Stream que contiene el resultado de aplicar la función pasada por parámetro a todos los elementos del Stream. Transforma los elementos de T a R.
También existe en su versión “primitiva”:+mapToDouble(ToDoubleFunction<T>): DoubleStream+mapToInt(ToIntFunction<T>): IntStream+mapToLong(ToLongFunction<T>): LongStream
La ventaja de usar las versiones primitivas radica en que se evita el uso de Autoboxing y Unboxing, lo que en algunas situaciones puede ser deseado por temas de rendimiento.
Map
Reduce
Filter
![Page 34: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/34.jpg)
Stream APIOperaciones sobre colecciones de datos - Map
+flatMap(Function<T, Stream<R>):Stream<R>Permite transformar cada elemento en un Stream y al final concatenarlos en un solo Stream.
También existe en su versión “primitiva”:+flatMapToDouble(Function<T, DoubleStream): DoubleStream+flatMapToInt(Function<T, IntStream): IntStream+flatMapToLong(Function<T, LongStream): LongStream
La ventaja de usar las versiones primitivas radica en que se evita el uso de Autoboxing y Unboxing, lo que en algunas situaciones puede ser deseado por temas de rendimiento.
Map
Reduce
Filter
![Page 35: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/35.jpg)
Stream APIOperaciones sobre colecciones de datos - Map
Taller Lambdas y Stream APITaller
Lambdas y Stream APITallerTaller
Lambdas y Stream APITallerTaller
2
Stream<String>
map(s->s.split(“ “))
Stream<String[]>
distinct()
Stream<String[]>
count()ERROR!
![Page 36: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/36.jpg)
Stream APIOperaciones sobre colecciones de datos - Map
Taller Lambdas y Stream APITaller
Lambdas y Stream APITallerTaller
5
Stream<String>
map(s->s.split(“ “))
Stream<String[]>
distinct()
Stream<Stream<String>>
count()
flatMap(Arrays::stream)
Lambdas y Stream APITallerTaller
Lambdas y Stream APITaller
CORRECTO!
Stream<String>
![Page 37: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/37.jpg)
Stream APIOperaciones sobre colecciones de datos - Reduce
Operaciones terminales provocan que todas las operaciones intermedias sean ejecutadas.
Existen operaciones terminales que permiten obtener datos del Stream como: conteo, mínimo, máximo, búsqueda, y en general reducir el Stream a un valor.
Existen algunas operaciones terminales cuyo propósito es el consumo de los elementos del Stream, por ejemplo: +foreach(Consumer<T>):void
Existen otras operaciones terminales que permiten recolectar los elementos de un Stream en estructuras mutables.
Map
Reduce
Filter
![Page 38: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/38.jpg)
Stream APIOperaciones sobre colecciones de datos – Reduce - Agregación
Entre las operaciones terminales que permiten obtener datos del Stream tenemos:
+count():long -> Retorna la cantidad de elementos en el Stream
+max(Comparator<T>):Optional<T> -> Retorna el elemento máximo del Stream basado en el comparador pasado por parámetro. Nótese que el retorno es de tipo Optional.
+min(Comparator<T>):Optional<T> -> Retorna el elemento mínimo del Stream basado en el comparador pasado por parámetro. Nótese que el retorno es de tipo Optional.
Map
Reduce
Filter
![Page 39: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/39.jpg)
Stream APIOperaciones sobre colecciones de datos – Reduce - Búsqueda
+allMatch(Predicate<T>):boolean -> Verifica si todos los elementos del Stream satisfacen el predicado pasado por parámetro. Si alguno no lo cumple, para la verificación y retorna falso.
+anyMatch(Predicate<T>):boolean -> Verifica si alguno de los elementos del Stream satisface el predicado pasado por parámetro. Si alguno lo cumple, para la verificación y retorna verdadero.
+noneMatch(Predicate<T>):boolean -> Verifica si todos los elementos del Stream NO satisfacen el predicado pasado por parámetro. Si alguno SI lo cumple, para la verificación y retorna false.
+findAny():Optional<T> -> Retorna algún elemento del Stream. Nótese el retorno es de tipo Optional.
+findFirst():Optional<T>: Retorna el primer elemento del Stream. Nótese el retorno es de tipo Optional.
Map
Reduce
Filter
![Page 40: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/40.jpg)
Stream APIOperaciones sobre colecciones de datos – Reduce
+reduce(BinaryOperator<T>):Optional<T>Realiza la reducción del Stream usando una función asociativa.
+reduce(T, BinaryOperator<T>):TRealiza la reducción del Stream usando un valor inicial y una función asociativa.
List<Integer> numeros = …
//Obtiene el posible número mayor par del StreamOptional<Integer> opt = numeros
.stream() .filter(x -> x % 2 == 0) .reduce(Integer::max);
//Obtiene la suma de los elementos del StreamInteger suma = numeros
.stream() .reduce(0, (x,y) -> x + y);
![Page 41: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/41.jpg)
Stream APIOperaciones sobre colecciones de datos – Reduce - Collectors
collect es una operación terminal que permite recolectar los elementos de un Stream.
Collectors es una clase utilitaria que provee métodos estáticos que retornan los recolectores más usados. Dichos recolectores pueden ser agrupados en 3 tipos:
● Reducción y resúmen: Reducen el Stream y permite obtener valores agregados.
● Agrupamiento: Agrupa elementos en un Map usando una función de clasificación.
● Particionamiento: Agrupamiento donde la función de clasificación es un predicado. Agrupa los elementos en un Map de 2 llaves: false y true
Import static java.util.stream.Collectors.*;...List<Integer> numeros = …
//Reducción y resúmen: Cuentalong cuenta = numeros.stream().collect(counting());
//Reducción y resúmen: Sumaint suma = numeros
.stream() .collect(summingInt(x -> x.intValue()));
//Reducción y resúmen: Objeto resúmenIntSummaryStatistics res = numeros
.stream()
.collect(summarizingInt(Integer::intValue));
//Reducción y resúmen: Unión de cadenasString csv = numeros.stream().map(Object::toString)
.collect(joining(", "));
summarizingLongsummarizingDouble
summingLongsummingDouble
![Page 42: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/42.jpg)
Stream APIOperaciones sobre colecciones de datos – Reduce - Collectors
Import static java.util.stream.Collectors.*;…List<Empleado> empleados = …
// AgrupamientoMap<String, List<Empleado>> porDept = empleados
.stream() .collect(groupingBy(Empleado::getDepartmento));
Map<String, Long> deptCant = empleados .stream()
.collect(groupingBy(Empleado::getDepartmento), counting());
Map<String, Map<String, List<Empleado>>> dptoCiu = null;dptoCiu = empleados
.stream() .collect(groupingBy(Empleado::getDepartamento, groupingBy(Empleado::getCiudad)));
Función de clasificación
En el Map quedan solo las llavesque tengan valores
Segundo collector permiteagrupar n-niveles
Segundo collector permiteContar la cantidad de elementos
![Page 43: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/43.jpg)
Stream APIOperaciones sobre colecciones de datos – Reduce - Collectors
Import static java.util.stream.Collectors.*;…List<Estudiante> estudiantes = …
//Estudiantes separados entre los que ganaron y perdieron el cursoMap<Boolean, List<Estudiante>> valoracion = estudiantes
.stream() .collect(partitioningBy(s -> s.getNota() >= 3.0));
//Cantidad de estudiantes separados entre los que ganaron y perdieron el cursoMap<Boolean, Long> valoracion = estudiantes
.stream() .collect(partitioningBy(s -> s.getNota() >= 3.0, counting()));
Función de clasificación
Segundo collector permitecontar la cantidad de elementos
particionar n-niveles, etc.
![Page 44: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/44.jpg)
Stream APIDebug
+peek(Consumer<T>):Stream<T>● Operación Intermedia● Cada elemento es pasado al Consumer● No modificar los elementos del Stream
Cuando se requiera definir breakpoints● Usar métodos de referencia● Usar peek entre operaciones intermedias
List<String> palabras = ...List<String> unicas = palabras.stream() .flatMap(w -> Stream.of(w.split(“ “)))
.peek(s -> s.toString()) .map(String::toLowerCase)
.peek(s -> metodoReferencia(s)) .distinct() .collect(Collectors.toList());
![Page 45: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/45.jpg)
Stream APIStreams Paralelos
Propiedades de un Stream Paralelo:
1. Usa Fork/Join internamente
2. Usar +parallel():Stream para convertir a paralelo.
3. Usar +sequential():Stream para convertir a secuencial.
4. La última llamada a +parallel():Stream o +sequential():Stream es la que se tiene en cuenta.
5. ¿Cuántos hilos en paralelo? Runtime.getRuntime.availableProcessors()
6. Propiedad: "java.util.concurrent.ForkJoinPool.common.parallelism" modifica valor por defecto
7. El uso de Streams en Paralelo requiere más trabajo, no siempre terminará más rápido que Streams secuenciales.
![Page 46: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/46.jpg)
Stream APIStreams Paralelos - ¿Cuándo usarlos?
Consideraciones a tener en cuenta si se desea usar Streams en Paralelo:
1. Medir primero ● N = Número de items● Q = costo de procesar un item● N*Q = Costo total de las operaciones. Mientras más grande, mejor usar Streams Paralelos
2. Evitar el Autoboxing y Unboxing
3. Algunas operaciones no se comportan bien en paralelo● +limit(long):Stream<T> ● +findFirst():Optional<T> ● +sorted():Stream<T> ● +distinct():Stream<T>
4. Usar estructuras que sean fáciles de descomponer● ArrayList -> Exelente● HashSet, TreeSet -> Bien● LinkedList -> Mal
![Page 47: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/47.jpg)
Enlaces de interés
Java SE 8 API docshttp://download.java.net/jdk8/docs/api/
JDK 8 Downloadhttp://www.oracle.com/technetwork/java/javase/overview/
ArtículosLambdas y API Stream Parte 1Lambdas y API Stream Parte 2
Taller Prácticohttps://github.com/aalopez/lambdas-lab
Java 8 in Actionhttp://www.manning.com/urma/
![Page 48: Lambdas y API Stream #PerúJUG #Java20](https://reader031.vdocuments.us/reader031/viewer/2022021921/58e9f1c91a28aba2208b5a81/html5/thumbnails/48.jpg)