SlideShare una empresa de Scribd logo
Perú JUG
DIC-2015
Alexis López
@aa_lopez
Agenda
Expresiones Lambda
Stream API
Taller Práctico
11
22
33
Expresiones Lambda
Funciones 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
Expresiones Lambda
Funciones 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
Expresiones Lambda
Funciones 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 encapsula
la condición
Expresiones Lambda
Funciones como valores/parámetros
…
List<Apple> inventory = ...
//Separar manzanas por color
List<Apple> greenApples = filterApples(inventory, new
AppleGreenColorPredicate());
//Separar manzanas por peso
List<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...
Expresiones Lambda
Funciones 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...
Expresiones Lambda
Funciones 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
Expresiones Lambda
Definició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
Expresiones Lambda
Definición
Ejemplos de expresiones lambda:
(int a, int b) -> a + b
a -> 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 Cuerpo
Operador
lambda
Expresiones Lambda
Definiciones – 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);
}
…
}
Expresiones Lambda
Definiciones – 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 concretas
2. Implementaciones en subinterfaces
3. 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.
Expresiones Lambda
Definiciones – 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
}
}
Expresiones Lambda
Definiciones – 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
Expresiones Lambda
Definiciones – 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…).
@FunctionalInterface
Indica al compilador que debe
verificar si se trata de una interfase
funcional.
@FunctionalInterface
public 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(…); }
Expresiones Lambda
Definiciones – Interface Funcional – 4 Grandes Grupos
@FunctionalInterface
public interface Supplier<T> {
T get();
//Otros métodos...
}
@FunctionalInterface
public interface Function<T, R> {
R apply(T);
//Otros métodos...
}
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
//Otros métodos...
}
@FunctionalInterface
public 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
Expresiones Lambda
Definiciones – 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
Expresiones Lambda
Definiciones – 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
Expresiones Lambda
Definiciones – Inferencia de tipos - Casos especiales
//Misma expresión lambda, diferentes interfaces funcionales
Callable<Integer> c = () -> 42;
PrivilegedAction<Integer> p = () -> 42;
//void-compatibility rule
List<String> list = ...
Predicate<String> p = s -> list.add(s);
Consumer<String> c = s -> list.add(s);
Aunque el método abstracto de Consumer
retorna void, no hay error de compilación
Expresiones Lambda
Definiciones – 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ón
before = 10000;
}
class SessionManager {
long before = ...;
void expire(File root) {
...
root.listFiles(File p -> checkExpiry(p.lastModified(),
this.before));
}
boolean checkExpiry(long time, long expiry) { ... }
}
Expresiones Lambda
Definiciones – 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áticos
Métodos de Instancia de un objeto
Métodos de Instancia de algún tipo
Constructores
//Uso para métodos estáticos
Clase::metodoEstatico
//Uso para métodos de instancia de un objeto existente
Objeto::metodoDeInstancia
//Uso para métodos de instancia de algún tipo de objeto
Tipo::metodoDeInstancia
//Uso para constructores
Clase::new
public class Person {
String name;
LocalDate birthday;
//gets…sets…
public static int compareByAge(Person a, Person b) {
return a.birthday.compareTo(b.birthday);
}
}
Expresiones Lambda
Definiciones – 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 lambdas
Arrays.sort(personArray, (a, b) -> Person.compareByAge(a, b));
//Ordenar el arreglo usando métodos de referencia
Arrays.sort(personArray, Person::compareByAge);
}
}
Expresiones Lambda
Definiciones – 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 lambdas
Arrays.sort(personArray, (a,b)->myComparisonProvider.compareByName(a, b));
//Ordenar el arreglo usando métodos de referencia
Arrays.sort(personArray, myComparisonProvider::compareByName);
}
}
Expresiones Lambda
Definiciones – 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 lambdas
Arrays.sort(stringArray, (a, b) -> a.compareToIgnoreCase(b));
//Ordenar el arreglo usando métodos de referencia
Arrays.sort(stringArray, String::compareToIgnoreCase);
}
}
Expresiones Lambda
Definiciones – Métodos de Referencia::Constructores
public class Testing
{
public static void main(String… args)
{
//Crear una persona usando lambdas
Supplier<Persona> s1 = () -> new Persona();
Persona p1 = s1.get();
//Crear una persona usando métodos de referencia
Supplier<Persona> s1 = Persona::new;
Persona p1 = s1.get();
}
}
Expresiones Lambda
Definiciones – Métodos de Referencia::Constructores
public class Manzana{
private int peso;
public Manzana(int w){ peso = w;}
}
…
//Crear una manzana usando lambdas
Function<Integer, Manzana> f1 = (w) -> new Manzana(w);
Manzana m1 = f1.apply(100);
//Crear una manzana usando métodos de referencia
Function<Integer, Manzana> f1 = Manzana::new;
Manzana m1 = f1.apply(100);
...
Expresiones Lambda
Definiciones – 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 complejos
Predicate<String> p1 = s -> s.length() > 3;
Predicate<String> p2 = s -> s.charAt(0) == 'A';
Predicate<String> p3 = ...
//Precedencia de izquierda a derecha
Predicate<String> p4 = p1.or(p2).and(p3).negate();
//Composición de funciones
Function<String, Integer> f1 = String::length;
Function<Integer, Integer> f2 = i -> i * 2;
//Primero aplica f1 y al resultado aplica f2
Function<String, Integer> f3 = f1.andThen(f2);
//Composición de comparadores
Comparator<String> c1 = (a,b) -> a.length() - b.length();
Comparator<String> c2 = String::compareTo;
//Primero compare con c1 y si son iguales use c2
Comparator<String> c3 = c1.thenComparing(c2);
Stream API
Definiciones - 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
Stream API
Definiciones - Stream
Un Stream está compuesto de tres (3) partes:
1. Una fuente de información
2. Cero o más operaciones intermedias
3. 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 intermedias
Operación terminal
Stream API
Definiciones - 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
Stream API
Definiciones – 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.
Stream API
Operaciones 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
Stream API
Operaciones 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
Stream API
Operaciones 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
Stream API
Operaciones 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!
Stream API
Operaciones 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>
Stream API
Operaciones 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
Stream API
Operaciones 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
Stream API
Operaciones 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
Stream API
Operaciones 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>):T
Realiza 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 Stream
Optional<Integer> opt = numeros
.stream()
.filter(x -> x % 2 == 0)
.reduce(Integer::max);
//Obtiene la suma de los elementos del Stream
Integer suma = numeros
.stream()
.reduce(0, (x,y) -> x + y);
Stream API
Operaciones 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: Cuenta
long cuenta = numeros.stream().collect(counting());
//Reducción y resúmen: Suma
int suma = numeros
.stream()
.collect(summingInt(x -> x.intValue()));
//Reducción y resúmen: Objeto resúmen
IntSummaryStatistics res = numeros
.stream()
.collect(summarizingInt(Integer::intValue));
//Reducción y resúmen: Unión de cadenas
String csv = numeros.stream().map(Object::toString)
.collect(joining(", "));
summarizingLong
summarizingDouble
summingLong
summingDouble
Stream API
Operaciones sobre colecciones de datos – Reduce - Collectors
Import static java.util.stream.Collectors.*;
…
List<Empleado> empleados = …
// Agrupamiento
Map<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 llaves
que tengan valores
Segundo collector permite
agrupar n-niveles
Segundo collector permite
Contar la cantidad de elementos
Stream API
Operaciones sobre colecciones de datos – Reduce - Collectors
Import static java.util.stream.Collectors.*;
…
List<Estudiante> estudiantes = …
//Estudiantes separados entre los que ganaron y perdieron el curso
Map<Boolean, List<Estudiante>> valoracion = estudiantes
.stream()
.collect(partitioningBy(s -> s.getNota() >= 3.0));
//Cantidad de estudiantes separados entre los que ganaron y perdieron el curso
Map<Boolean, Long> valoracion = estudiantes
.stream()
.collect(partitioningBy(s -> s.getNota() >= 3.0, counting()));
Función de clasificación
Segundo collector permite
contar la cantidad de elementos
particionar n-niveles, etc.
Stream API
Debug
+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());
Stream API
Streams 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.
Stream API
Streams 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
Enlaces de interés
Java SE 8 API docs
http://download.java.net/jdk8/docs/api/
JDK 8 Download
http://www.oracle.com/technetwork/java/javase/overview/
Artículos
Lambdas y API Stream Parte 1
Lambdas y API Stream Parte 2
Taller Práctico
https://github.com/aalopez/lambdas-lab
Java 8 in Action
http://www.manning.com/urma/
Lambdas y API Stream #PerúJUG #Java20

Más contenido relacionado

La actualidad más candente

Pascal [modo de compatibilidad]
Pascal [modo de compatibilidad]Pascal [modo de compatibilidad]
Pascal [modo de compatibilidad]
Zamantha Gonzalez Universidad Nacional Abierta
 
Taller analisis semantico
Taller analisis semanticoTaller analisis semantico
Taller analisis semantico
Alvaro Cedeño
 
Portafolio de evidencias
Portafolio de evidenciasPortafolio de evidencias
Portafolio de evidencias
Héctor Díaz Ponce Inda
 
Elementos basicos c++
Elementos basicos c++Elementos basicos c++
Elementos basicos c++
Tensor
 
Funciones lenguaje c modulo4
Funciones lenguaje c modulo4Funciones lenguaje c modulo4
Funciones lenguaje c modulo4
flaquita_dany
 
Ppiosprogramacion 090925153826-phpapp01[1]Principios de Programación
Ppiosprogramacion 090925153826-phpapp01[1]Principios de Programación Ppiosprogramacion 090925153826-phpapp01[1]Principios de Programación
Ppiosprogramacion 090925153826-phpapp01[1]Principios de Programación
Vladimir Pomares
 
Lex yacc
Lex yaccLex yacc
Bt haskell-1
Bt haskell-1Bt haskell-1
Bt haskell-1
Rosana Alvarez
 
Análisis semántico
Análisis semánticoAnálisis semántico
Análisis semántico
Andres Pozo
 
Complementos
ComplementosComplementos
Complementos
Tensor
 
Unidad1 2 Lenguajes y automatas
Unidad1 2  Lenguajes y automatasUnidad1 2  Lenguajes y automatas
Unidad1 2 Lenguajes y automatas
Sergio Lara Guevara
 
Unidad 2 programación estructurada
Unidad 2 programación estructuradaUnidad 2 programación estructurada
Unidad 2 programación estructurada
Roberth Camana
 
Tema 7
Tema 7Tema 7
Tema 7
UH
 
vectores y matrices
vectores y matricesvectores y matrices
vectores y matrices
Marlene Pallo
 
Funciones con vectores y matrices1
Funciones con vectores y matrices1Funciones con vectores y matrices1
Funciones con vectores y matrices1
Marlene Pallo
 
71456126 enunciado-practica1-afd
71456126 enunciado-practica1-afd71456126 enunciado-practica1-afd
71456126 enunciado-practica1-afd
Angel Herrera Sara
 
Funciones
FuncionesFunciones
Funciones
Giovani Ramirez
 
Java 8: Expresiones Lambdas y API Stream BarCamp RD 2016
Java 8: Expresiones Lambdas y API Stream BarCamp RD 2016Java 8: Expresiones Lambdas y API Stream BarCamp RD 2016
Java 8: Expresiones Lambdas y API Stream BarCamp RD 2016
Eudris Cabrera
 
Yacc
YaccYacc

La actualidad más candente (19)

Pascal [modo de compatibilidad]
Pascal [modo de compatibilidad]Pascal [modo de compatibilidad]
Pascal [modo de compatibilidad]
 
Taller analisis semantico
Taller analisis semanticoTaller analisis semantico
Taller analisis semantico
 
Portafolio de evidencias
Portafolio de evidenciasPortafolio de evidencias
Portafolio de evidencias
 
Elementos basicos c++
Elementos basicos c++Elementos basicos c++
Elementos basicos c++
 
Funciones lenguaje c modulo4
Funciones lenguaje c modulo4Funciones lenguaje c modulo4
Funciones lenguaje c modulo4
 
Ppiosprogramacion 090925153826-phpapp01[1]Principios de Programación
Ppiosprogramacion 090925153826-phpapp01[1]Principios de Programación Ppiosprogramacion 090925153826-phpapp01[1]Principios de Programación
Ppiosprogramacion 090925153826-phpapp01[1]Principios de Programación
 
Lex yacc
Lex yaccLex yacc
Lex yacc
 
Bt haskell-1
Bt haskell-1Bt haskell-1
Bt haskell-1
 
Análisis semántico
Análisis semánticoAnálisis semántico
Análisis semántico
 
Complementos
ComplementosComplementos
Complementos
 
Unidad1 2 Lenguajes y automatas
Unidad1 2  Lenguajes y automatasUnidad1 2  Lenguajes y automatas
Unidad1 2 Lenguajes y automatas
 
Unidad 2 programación estructurada
Unidad 2 programación estructuradaUnidad 2 programación estructurada
Unidad 2 programación estructurada
 
Tema 7
Tema 7Tema 7
Tema 7
 
vectores y matrices
vectores y matricesvectores y matrices
vectores y matrices
 
Funciones con vectores y matrices1
Funciones con vectores y matrices1Funciones con vectores y matrices1
Funciones con vectores y matrices1
 
71456126 enunciado-practica1-afd
71456126 enunciado-practica1-afd71456126 enunciado-practica1-afd
71456126 enunciado-practica1-afd
 
Funciones
FuncionesFunciones
Funciones
 
Java 8: Expresiones Lambdas y API Stream BarCamp RD 2016
Java 8: Expresiones Lambdas y API Stream BarCamp RD 2016Java 8: Expresiones Lambdas y API Stream BarCamp RD 2016
Java 8: Expresiones Lambdas y API Stream BarCamp RD 2016
 
Yacc
YaccYacc
Yacc
 

Destacado

Juan Pablo Ii Oracion
Juan Pablo Ii OracionJuan Pablo Ii Oracion
Juan Pablo Ii Oracion
tereabacua
 
Leccion 13 La Conclusion Del Discruso Jac
Leccion 13  La Conclusion Del Discruso JacLeccion 13  La Conclusion Del Discruso Jac
Leccion 13 La Conclusion Del Discruso Jac
Samy
 
Encuentra más formas de hacer negocio / José Ignacio Porroche (Net2U)
Encuentra más formas de hacer negocio /  José Ignacio Porroche (Net2U)Encuentra más formas de hacer negocio /  José Ignacio Porroche (Net2U)
Encuentra más formas de hacer negocio / José Ignacio Porroche (Net2U)
ServiDocu
 
Open data listo
Open data listoOpen data listo
Open data listo
ooyola
 
Gpt cpe gerentes estrategicos
Gpt cpe gerentes estrategicosGpt cpe gerentes estrategicos
Gpt cpe gerentes estrategicos
ooyola
 
Publicar contenidos en internet
Publicar contenidos en internetPublicar contenidos en internet
Publicar contenidos en internet
Aida March
 
Notas de prensa asesinato Colombo
Notas de prensa asesinato ColomboNotas de prensa asesinato Colombo
Notas de prensa asesinato Colombo
María Virginia Bertetti
 
El Wiki
El WikiEl Wiki
El Wiki
jucive
 
El Mundo
El MundoEl Mundo
El Mundo
Tere
 
Europa Desde El Cielo
Europa Desde El CieloEuropa Desde El Cielo
Europa Desde El Cielo
Iago Fernández
 
Amor En La Biblioteca2
Amor En La Biblioteca2Amor En La Biblioteca2
Amor En La Biblioteca2
guest5ab891
 
Los Koooooookkkksssss
Los KoooooookkkksssssLos Koooooookkkksssss
Los Koooooookkkksssss
guestc19439
 
Actividad 4 investigación de posicionamiento
Actividad 4 investigación de posicionamientoActividad 4 investigación de posicionamiento
Actividad 4 investigación de posicionamiento
Kar Klom
 
Cuento
CuentoCuento
Cuento
escuela3de18
 
Sintaxis Y Gramatica
Sintaxis Y GramaticaSintaxis Y Gramatica
Sintaxis Y Gramatica
fanyeliza
 
Festival Cartagena Documento Compilatorio
Festival Cartagena Documento CompilatorioFestival Cartagena Documento Compilatorio
Festival Cartagena Documento Compilatorio
Germán De
 
Retenciones al agro
Retenciones al agroRetenciones al agro
Retenciones al agro
franciscovillamayor
 
Publiweb
PubliwebPubliweb
Publiweb
eder8
 
Susana F I N Q U E L I E V I C H, Guadalajara, C I U D A D R E D
Susana  F I N Q U E L I E V I C H,  Guadalajara,  C I U D A D  R E DSusana  F I N Q U E L I E V I C H,  Guadalajara,  C I U D A D  R E D
Susana F I N Q U E L I E V I C H, Guadalajara, C I U D A D R E D
Susana Finquelievich
 
Insolito2
Insolito2Insolito2
Insolito2
Iago Fernández
 

Destacado (20)

Juan Pablo Ii Oracion
Juan Pablo Ii OracionJuan Pablo Ii Oracion
Juan Pablo Ii Oracion
 
Leccion 13 La Conclusion Del Discruso Jac
Leccion 13  La Conclusion Del Discruso JacLeccion 13  La Conclusion Del Discruso Jac
Leccion 13 La Conclusion Del Discruso Jac
 
Encuentra más formas de hacer negocio / José Ignacio Porroche (Net2U)
Encuentra más formas de hacer negocio /  José Ignacio Porroche (Net2U)Encuentra más formas de hacer negocio /  José Ignacio Porroche (Net2U)
Encuentra más formas de hacer negocio / José Ignacio Porroche (Net2U)
 
Open data listo
Open data listoOpen data listo
Open data listo
 
Gpt cpe gerentes estrategicos
Gpt cpe gerentes estrategicosGpt cpe gerentes estrategicos
Gpt cpe gerentes estrategicos
 
Publicar contenidos en internet
Publicar contenidos en internetPublicar contenidos en internet
Publicar contenidos en internet
 
Notas de prensa asesinato Colombo
Notas de prensa asesinato ColomboNotas de prensa asesinato Colombo
Notas de prensa asesinato Colombo
 
El Wiki
El WikiEl Wiki
El Wiki
 
El Mundo
El MundoEl Mundo
El Mundo
 
Europa Desde El Cielo
Europa Desde El CieloEuropa Desde El Cielo
Europa Desde El Cielo
 
Amor En La Biblioteca2
Amor En La Biblioteca2Amor En La Biblioteca2
Amor En La Biblioteca2
 
Los Koooooookkkksssss
Los KoooooookkkksssssLos Koooooookkkksssss
Los Koooooookkkksssss
 
Actividad 4 investigación de posicionamiento
Actividad 4 investigación de posicionamientoActividad 4 investigación de posicionamiento
Actividad 4 investigación de posicionamiento
 
Cuento
CuentoCuento
Cuento
 
Sintaxis Y Gramatica
Sintaxis Y GramaticaSintaxis Y Gramatica
Sintaxis Y Gramatica
 
Festival Cartagena Documento Compilatorio
Festival Cartagena Documento CompilatorioFestival Cartagena Documento Compilatorio
Festival Cartagena Documento Compilatorio
 
Retenciones al agro
Retenciones al agroRetenciones al agro
Retenciones al agro
 
Publiweb
PubliwebPubliweb
Publiweb
 
Susana F I N Q U E L I E V I C H, Guadalajara, C I U D A D R E D
Susana  F I N Q U E L I E V I C H,  Guadalajara,  C I U D A D  R E DSusana  F I N Q U E L I E V I C H,  Guadalajara,  C I U D A D  R E D
Susana F I N Q U E L I E V I C H, Guadalajara, C I U D A D R E D
 
Insolito2
Insolito2Insolito2
Insolito2
 

Similar a Lambdas y API Stream #PerúJUG #Java20

Java 8
Java 8Java 8
Java 8
BVision
 
Java 8 introducción a expresiones lambdas y api stream
Java 8  introducción a expresiones lambdas y api streamJava 8  introducción a expresiones lambdas y api stream
Java 8 introducción a expresiones lambdas y api stream
Eudris Cabrera
 
Interfaces en C#
Interfaces en C#Interfaces en C#
Interfaces en C#
Germán Küber
 
Functional SE.pdf
Functional SE.pdfFunctional SE.pdf
Functional SE.pdf
HenryHernandez683776
 
Java8 : Más allá de las Expresiones Lambdas
Java8 :  Más allá de las Expresiones LambdasJava8 :  Más allá de las Expresiones Lambdas
Java8 : Más allá de las Expresiones Lambdas
Eudris Cabrera
 
Java 8: Más funcional que nunca
Java 8: Más funcional que nuncaJava 8: Más funcional que nunca
Java 8: Más funcional que nunca
Víctor Leonel Orozco López
 
Lenguajes de Programacion
Lenguajes de ProgramacionLenguajes de Programacion
Lenguajes de Programacion
Vladimir Pomares
 
Fundamentos De Algoritmia
Fundamentos De AlgoritmiaFundamentos De Algoritmia
Fundamentos De Algoritmia
cckokyco
 
Java Lambda
Java LambdaJava Lambda
Un vistazo a java 8
Un vistazo a java 8Un vistazo a java 8
Un vistazo a java 8
Germán González
 
Trabajo tutorial de visual C++
Trabajo tutorial de visual C++Trabajo tutorial de visual C++
Trabajo tutorial de visual C++
Bryangio2002
 
Lenguajes de Programación: Clases y objetos
Lenguajes de Programación: Clases y objetosLenguajes de Programación: Clases y objetos
Lenguajes de Programación: Clases y objetos
Luis Fernando Aguas Bucheli
 
Visual basic
Visual basicVisual basic
Visual basic
mellcv
 
Laboratorio interfaces
Laboratorio interfacesLaboratorio interfaces
Laboratorio interfaces
Andres Herrera Rodriguez
 
2) introduccion al lenguaje java
2) introduccion al lenguaje java2) introduccion al lenguaje java
2) introduccion al lenguaje java
Margarita Romero
 
2introduccionallenguajejava 141109171757-conversion-gate02
2introduccionallenguajejava 141109171757-conversion-gate022introduccionallenguajejava 141109171757-conversion-gate02
2introduccionallenguajejava 141109171757-conversion-gate02
Krizztiina Pacheko
 
INTRODUCCION LENGUAJE JAVA
INTRODUCCION LENGUAJE JAVAINTRODUCCION LENGUAJE JAVA
INTRODUCCION LENGUAJE JAVA
Karla Estefania Villanueva Epigmenio
 
Lenguaje de Alto Nivel (I Bimestre)
Lenguaje de Alto Nivel (I Bimestre)Lenguaje de Alto Nivel (I Bimestre)
Lenguaje de Alto Nivel (I Bimestre)
Videoconferencias UTPL
 
Portafolio de evidencias
Portafolio de evidenciasPortafolio de evidencias
Portafolio de evidencias
Héctor Díaz Ponce Inda
 
Metodos en java
Metodos en javaMetodos en java
Metodos en java
Ricardo Garcia
 

Similar a Lambdas y API Stream #PerúJUG #Java20 (20)

Java 8
Java 8Java 8
Java 8
 
Java 8 introducción a expresiones lambdas y api stream
Java 8  introducción a expresiones lambdas y api streamJava 8  introducción a expresiones lambdas y api stream
Java 8 introducción a expresiones lambdas y api stream
 
Interfaces en C#
Interfaces en C#Interfaces en C#
Interfaces en C#
 
Functional SE.pdf
Functional SE.pdfFunctional SE.pdf
Functional SE.pdf
 
Java8 : Más allá de las Expresiones Lambdas
Java8 :  Más allá de las Expresiones LambdasJava8 :  Más allá de las Expresiones Lambdas
Java8 : Más allá de las Expresiones Lambdas
 
Java 8: Más funcional que nunca
Java 8: Más funcional que nuncaJava 8: Más funcional que nunca
Java 8: Más funcional que nunca
 
Lenguajes de Programacion
Lenguajes de ProgramacionLenguajes de Programacion
Lenguajes de Programacion
 
Fundamentos De Algoritmia
Fundamentos De AlgoritmiaFundamentos De Algoritmia
Fundamentos De Algoritmia
 
Java Lambda
Java LambdaJava Lambda
Java Lambda
 
Un vistazo a java 8
Un vistazo a java 8Un vistazo a java 8
Un vistazo a java 8
 
Trabajo tutorial de visual C++
Trabajo tutorial de visual C++Trabajo tutorial de visual C++
Trabajo tutorial de visual C++
 
Lenguajes de Programación: Clases y objetos
Lenguajes de Programación: Clases y objetosLenguajes de Programación: Clases y objetos
Lenguajes de Programación: Clases y objetos
 
Visual basic
Visual basicVisual basic
Visual basic
 
Laboratorio interfaces
Laboratorio interfacesLaboratorio interfaces
Laboratorio interfaces
 
2) introduccion al lenguaje java
2) introduccion al lenguaje java2) introduccion al lenguaje java
2) introduccion al lenguaje java
 
2introduccionallenguajejava 141109171757-conversion-gate02
2introduccionallenguajejava 141109171757-conversion-gate022introduccionallenguajejava 141109171757-conversion-gate02
2introduccionallenguajejava 141109171757-conversion-gate02
 
INTRODUCCION LENGUAJE JAVA
INTRODUCCION LENGUAJE JAVAINTRODUCCION LENGUAJE JAVA
INTRODUCCION LENGUAJE JAVA
 
Lenguaje de Alto Nivel (I Bimestre)
Lenguaje de Alto Nivel (I Bimestre)Lenguaje de Alto Nivel (I Bimestre)
Lenguaje de Alto Nivel (I Bimestre)
 
Portafolio de evidencias
Portafolio de evidenciasPortafolio de evidencias
Portafolio de evidencias
 
Metodos en java
Metodos en javaMetodos en java
Metodos en java
 

Lambdas y API Stream #PerúJUG #Java20

  • 3. Expresiones Lambda Funciones 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
  • 4. Expresiones Lambda Funciones 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
  • 5. Expresiones Lambda Funciones 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 encapsula la condición
  • 6. Expresiones Lambda Funciones como valores/parámetros … List<Apple> inventory = ... //Separar manzanas por color List<Apple> greenApples = filterApples(inventory, new AppleGreenColorPredicate()); //Separar manzanas por peso List<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...
  • 7. Expresiones Lambda Funciones 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...
  • 8. Expresiones Lambda Funciones 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
  • 9. Expresiones Lambda Definició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
  • 10. Expresiones Lambda Definición Ejemplos de expresiones lambda: (int a, int b) -> a + b a -> 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 Cuerpo Operador lambda
  • 11. Expresiones Lambda Definiciones – 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); } … }
  • 12. Expresiones Lambda Definiciones – 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 concretas 2. Implementaciones en subinterfaces 3. 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.
  • 13. Expresiones Lambda Definiciones – 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 } }
  • 14. Expresiones Lambda Definiciones – 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
  • 15. Expresiones Lambda Definiciones – 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…). @FunctionalInterface Indica al compilador que debe verificar si se trata de una interfase funcional. @FunctionalInterface public 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(…); }
  • 16. Expresiones Lambda Definiciones – Interface Funcional – 4 Grandes Grupos @FunctionalInterface public interface Supplier<T> { T get(); //Otros métodos... } @FunctionalInterface public interface Function<T, R> { R apply(T); //Otros métodos... } @FunctionalInterface public interface Predicate<T> { boolean test(T t); //Otros métodos... } @FunctionalInterface public 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
  • 17. Expresiones Lambda Definiciones – 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
  • 18. Expresiones Lambda Definiciones – 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
  • 19. Expresiones Lambda Definiciones – Inferencia de tipos - Casos especiales //Misma expresión lambda, diferentes interfaces funcionales Callable<Integer> c = () -> 42; PrivilegedAction<Integer> p = () -> 42; //void-compatibility rule List<String> list = ... Predicate<String> p = s -> list.add(s); Consumer<String> c = s -> list.add(s); Aunque el método abstracto de Consumer retorna void, no hay error de compilación
  • 20. Expresiones Lambda Definiciones – 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ón before = 10000; } class SessionManager { long before = ...; void expire(File root) { ... root.listFiles(File p -> checkExpiry(p.lastModified(), this.before)); } boolean checkExpiry(long time, long expiry) { ... } }
  • 21. Expresiones Lambda Definiciones – 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áticos Métodos de Instancia de un objeto Métodos de Instancia de algún tipo Constructores //Uso para métodos estáticos Clase::metodoEstatico //Uso para métodos de instancia de un objeto existente Objeto::metodoDeInstancia //Uso para métodos de instancia de algún tipo de objeto Tipo::metodoDeInstancia //Uso para constructores Clase::new public class Person { String name; LocalDate birthday; //gets…sets… public static int compareByAge(Person a, Person b) { return a.birthday.compareTo(b.birthday); } }
  • 22. Expresiones Lambda Definiciones – 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 lambdas Arrays.sort(personArray, (a, b) -> Person.compareByAge(a, b)); //Ordenar el arreglo usando métodos de referencia Arrays.sort(personArray, Person::compareByAge); } }
  • 23. Expresiones Lambda Definiciones – 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 lambdas Arrays.sort(personArray, (a,b)->myComparisonProvider.compareByName(a, b)); //Ordenar el arreglo usando métodos de referencia Arrays.sort(personArray, myComparisonProvider::compareByName); } }
  • 24. Expresiones Lambda Definiciones – 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 lambdas Arrays.sort(stringArray, (a, b) -> a.compareToIgnoreCase(b)); //Ordenar el arreglo usando métodos de referencia Arrays.sort(stringArray, String::compareToIgnoreCase); } }
  • 25. Expresiones Lambda Definiciones – Métodos de Referencia::Constructores public class Testing { public static void main(String… args) { //Crear una persona usando lambdas Supplier<Persona> s1 = () -> new Persona(); Persona p1 = s1.get(); //Crear una persona usando métodos de referencia Supplier<Persona> s1 = Persona::new; Persona p1 = s1.get(); } }
  • 26. Expresiones Lambda Definiciones – Métodos de Referencia::Constructores public class Manzana{ private int peso; public Manzana(int w){ peso = w;} } … //Crear una manzana usando lambdas Function<Integer, Manzana> f1 = (w) -> new Manzana(w); Manzana m1 = f1.apply(100); //Crear una manzana usando métodos de referencia Function<Integer, Manzana> f1 = Manzana::new; Manzana m1 = f1.apply(100); ...
  • 27. Expresiones Lambda Definiciones – 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 complejos Predicate<String> p1 = s -> s.length() > 3; Predicate<String> p2 = s -> s.charAt(0) == 'A'; Predicate<String> p3 = ... //Precedencia de izquierda a derecha Predicate<String> p4 = p1.or(p2).and(p3).negate(); //Composición de funciones Function<String, Integer> f1 = String::length; Function<Integer, Integer> f2 = i -> i * 2; //Primero aplica f1 y al resultado aplica f2 Function<String, Integer> f3 = f1.andThen(f2); //Composición de comparadores Comparator<String> c1 = (a,b) -> a.length() - b.length(); Comparator<String> c2 = String::compareTo; //Primero compare con c1 y si son iguales use c2 Comparator<String> c3 = c1.thenComparing(c2);
  • 28. Stream API Definiciones - 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
  • 29. Stream API Definiciones - Stream Un Stream está compuesto de tres (3) partes: 1. Una fuente de información 2. Cero o más operaciones intermedias 3. 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 intermedias Operación terminal
  • 30. Stream API Definiciones - 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
  • 31. Stream API Definiciones – 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.
  • 32. Stream API Operaciones 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
  • 33. Stream API Operaciones 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
  • 34. Stream API Operaciones 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
  • 35. Stream API Operaciones 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!
  • 36. Stream API Operaciones 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>
  • 37. Stream API Operaciones 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
  • 38. Stream API Operaciones 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
  • 39. Stream API Operaciones 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
  • 40. Stream API Operaciones 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>):T Realiza 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 Stream Optional<Integer> opt = numeros .stream() .filter(x -> x % 2 == 0) .reduce(Integer::max); //Obtiene la suma de los elementos del Stream Integer suma = numeros .stream() .reduce(0, (x,y) -> x + y);
  • 41. Stream API Operaciones 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: Cuenta long cuenta = numeros.stream().collect(counting()); //Reducción y resúmen: Suma int suma = numeros .stream() .collect(summingInt(x -> x.intValue())); //Reducción y resúmen: Objeto resúmen IntSummaryStatistics res = numeros .stream() .collect(summarizingInt(Integer::intValue)); //Reducción y resúmen: Unión de cadenas String csv = numeros.stream().map(Object::toString) .collect(joining(", ")); summarizingLong summarizingDouble summingLong summingDouble
  • 42. Stream API Operaciones sobre colecciones de datos – Reduce - Collectors Import static java.util.stream.Collectors.*; … List<Empleado> empleados = … // Agrupamiento Map<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 llaves que tengan valores Segundo collector permite agrupar n-niveles Segundo collector permite Contar la cantidad de elementos
  • 43. Stream API Operaciones sobre colecciones de datos – Reduce - Collectors Import static java.util.stream.Collectors.*; … List<Estudiante> estudiantes = … //Estudiantes separados entre los que ganaron y perdieron el curso Map<Boolean, List<Estudiante>> valoracion = estudiantes .stream() .collect(partitioningBy(s -> s.getNota() >= 3.0)); //Cantidad de estudiantes separados entre los que ganaron y perdieron el curso Map<Boolean, Long> valoracion = estudiantes .stream() .collect(partitioningBy(s -> s.getNota() >= 3.0, counting())); Función de clasificación Segundo collector permite contar la cantidad de elementos particionar n-niveles, etc.
  • 44. Stream API Debug +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());
  • 45. Stream API Streams 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.
  • 46. Stream API Streams 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
  • 47. Enlaces de interés Java SE 8 API docs http://download.java.net/jdk8/docs/api/ JDK 8 Download http://www.oracle.com/technetwork/java/javase/overview/ Artículos Lambdas y API Stream Parte 1 Lambdas y API Stream Parte 2 Taller Práctico https://github.com/aalopez/lambdas-lab Java 8 in Action http://www.manning.com/urma/