SlideShare ist ein Scribd-Unternehmen logo
1 von 60
Downloaden Sie, um offline zu lesen
Java 8: Expresiones
Lambdas y API Stream en
la Práctica
Eudris Cabrera
Noviembre 19, 2016
#BarCampRD2016
Eudris Cabrera
Graduado de Ingeniería Telemática en la PUCMM.
Entusiasta de la tecnología y el software libre,
desarrollador Java, instructor ocasional (Java / Linux),
aficionado del béisbol/sóftbol y los bailes latinos.
En el tiempo libre, escribe artículos, realiza charlas,
participa en eventos tecnológicos y ayuda en la
revisión de documentación técnica en el mundo Java
y el código abierto.
Breve Reseña sobre Java 8
Expresiones Lambda
Introducción al Stream API
Conceptos Avanzados sobre
Lambda y API Stream
Consejos Prácticos
Agenda
Java SE 8
Liberado en marzo del 2014, es la
plataforma que incluye la actualización
más grande para el modelo de
programación Java desde el lanzamiento
de la plataforma en 1996.
Incluye nuevas funcionalidades e
incorpora las características de los
lenguaje funcionales.
Funciones como entidades de primer nivel
La programación funcional establece que las funciones
(métodos) sean definidas como entidades de primer nivel
¿Qué
significa
eso?
Qué las funciones pueden ser usada de la misma forma que
usamos enteros (integers) o cadenas de caracteres(strings).
Se pueden pasar funciones como parámetros a otras funciones
y pueden ser retornada como resultado de otras funciones.
Ejemplo
Funciones como entidades de primer nivel
public void printTeamsWithPredicate(List<Team> teams, Predicate<Team> tester){
for (Team t : teams) {
if(tester.test(t)){
System.out.println(""+ t.toString());
}
}
}
Predicate<Team> hasNotWonWS = new Predicate<Team>() {
@Override
public boolean test(Team t) {
return !t.isHasWonWoldSeries();
}
};
printTeamsWithPredicate(teams, hasNotWonWS);
Ejemplo
Ejemplo anterior usando expresiones lambdas.
printTeamsWithPredicate(teams, (Team t) -> !t.isHasWonWoldSeries());
Expresiones lambdas
Una expresión lambda representa una
función anónima.
λx → x+x
Función anónima que toma un número x y devuelve el resultado x + x.
Sintaxis
() -> System.out.println("Hello Lambda")
x -> x + 10
(int x, int y) -> { return x + y; }
(String x, String y) -> x.length() – y.length()
(int a, int b) --> a + b
(int a) --> a + 1
(int a, int b) --> {
System.out.println(a + b);
return a + b;
}
() --> new ArrayList();
Una expresión lambda se compone de un conjunto de
parámetros, un operador lambda (->) y un cuerpo de la
función.
¿Por qué Java necesita
Expresiones Lambda?
● Java necesitaba cambios para simplificar la
codificación paralela.
● Es muy útil para evitar tener que escribir
métodos que sólo utilizamos una vez.
● Simplifica cómo pasar comportamiento como
un parámetro (podemos pasar expresiones
lambda a métodos como argumentos).
Interfaces Funcionales
En Java, una interfaz funcional es, básicamente, una interfaz con un
único método abstracto.
Este tipo de interfaces también son conocidos como tipos SAM
(Single Abstract Method).
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Runnable r = () -> System.out.println("Hello Lambda");
Metodos Predeterminados("Default")
● Tradicionalmente, las interfaces no pueden tener definiciones de método
(sólo declaraciones).
● Métodos predeterminados (Default) permite realizar implementaciones por
defecto dentro de una interfaz.
public interface A {
default void foo() {
System.out.println("Calling A.foo()");
}
}
public class Clazz implements A {
}
java.util.function
● Predicate<T> - Recibe un argumento tipo T y retorna un booleano.
● Consumer<T> - una acción que se realiza sobre un objeto
● Function<T,R> - a funcion que transforma un valor T a R
● Supplier<T> - provee una instancia de T (como un factory).
● UnaryOperator<T> - Forma especializada de Function. Recibe un
valor T como argumento y retorna del un valor del mismo tipo T.
● BinaryOperator<T> - Forma especializada de BiFunction. Recibe
dos argumentos y retorna un resultado, todos del mismo tipo.
Introducción al API Stream
Stream:
● Representa una abstracción para
especificar cálculos agregados
(acumulativos).
● Simplifica la descripción de los cálculos
agregados (laziness,paralelismo).
Elementos de un Stream
Un Stream se compone de 3 elementos:
● Un origen
● Cero o más operaciones intermedias
● Una operación final (salida o un resultado)
Ejemplo
long totalEquipos = teams.stream()
.filter(t -> t.isHasWonWoldSeries())
.mapToInt(Team::getLastTimeWonWorldSeries)
.count();
Source
Intermediate
operations
Terminal
operation
java.util.stream
filter/map/reduce para Java
java.util.stream
List<MLBTeam> teams = ..;
// sequential version
Stream stream = students.stream();
//parallel version
Stream parallelStream = students.parallelStream();
java.util.stream
Stream Sources (Origen)
● Collections
● Generadores (Generators)
● Otros Streams
Ejemplo
Antes de Java 8
Collection<Team> worldSeriesWinners = new ArrayList<>();
for (Team team : teams) {
if (team.isHasWonWoldSeries()) {
worldSeriesWinners.add(team);
}
}
Java 8
Collection<Team> worldSeriesWinners = teams
.stream()
.filter(p -> p.isHasWonWoldSeries())
.collect(Collectors.toList());
Ejemplo
Procesar la siguiente lista para que solamente contenga cadena de caracteres impares y en letra minúscula.
List<String> list = Arrays.asList("BarCamp", "MongoDB", "10Gen", "TokuMX", "Nagios", "PUCMM", "Ruby", "JSON", "JSON");
Solución usando clase anónima
List<String> newList = list
.stream()
.filter(new Predicate<String>() {
@Override
public boolean test(String t) {
return (t.length() % 2)==1;
}
}).map(String::toLowerCase)
.collect(Collectors.toList());
Ejemplo
Procesar la siguiente lista para que solamente contenga cadena de caracteres impares y en letra minúscula.
List<String> list = Arrays.asList("BarCamp", "MongoDB", "10Gen", "TokuMX", "Nagios", "PUCMM", "Ruby", "JSON", "JSON");
Solución usando expresiones lambdas
List<String> newList = list
.stream()
.filter(s -> (s.length() % 2)==1)
.map(String::toLowerCase)
.collect(Collectors.toList());
Ejemplo
Usando Generadores (Generators)
OptionalInt one = IntStream.generate(() -> 1)
.limit(10)
.distinct()
.findFirst();
Method References
Nos permiten utilizar un método como una expresión lambda.
Formato: target_reference::method_name
class Person {
private String name;
private int age;
public int getAge() {return this.age;}
public String getName() {return this.name;}
}
Person[] people = ...;
Comparator<Person> byName = Comparator.comparing(Person::getName);
Arrays.sort(people, byName);
Method References
(Tipos)
● Método estático (ClassName::methName)
● Un método de instancia de un objeto particular
(instanceRef::methName)
● Un método super de un objeto particular (super::methName)
● Un método de instancia de un objeto arbitrario de un tipo particular
(ClassName::methName)
● Un constructor de una clase (ClassName::new)
● Un constructor de un arreglo (TypeName[]::new)
java.util.stream
Operaciones Intermedias
● .filter
● .map
● .flatMap
● .peek
● .distinct
● .sorted
● .limit
● .substream
Ejemplo
a) filter(Predicate predicate)
OptionalInt oldestYear = teams.stream()
.filter(t -> t.isHasWonWoldSeries())
.mapToInt(Team::getLastTimeWonWorldSeries)
.min();
b) map(Function<? super T, ? extends R> mapper)
List<String> list = Arrays.asList("BarCamp", "MongoDB", "10Gen",
"TokuMX", "Nagios", "PUCMM", "Ruby", "JSON", "JSON");
List<String> newList = list
.stream()
.filter(s -> (s.length() % 2)==1)
.map(String::toLowerCase)
.collect(Collectors.toList());
OptionalInt one = IntStream
.generate(() -> 1)
.limit(10)
.distinct()
.findFirst();
limit(long maxSize)
distinct()
Ejemplo
a) flatMap(Function<T, Stream<R>):Stream<R>
Permite transformar cada elemento del Stream en otro Stream y al final concatenarlos todos en uno solo. Es un poco
confuso, pero pensemos que cuando tengamos un Stream<Stream<R>>, este método nos permitirá transformarlo en
Stream<R>.
List<String> lista = Arrays.asList("BarcampRD", "BarcampRD Lambdas y API Stream");
Stream stream = lista.stream()
.map(s -> s.split(" ")) // Stream<String[]>
.flatMap(Arrays::stream) // Stream<String>
.distinct(); // Stream<String> de 5 elementos
java.util.stream
Operaciones Finales (Terminal Operations)
● reducers like reduce(), count(), findAny(), findFirst()
● collectors (collect())
● forEach
● iterators
Ejemplo
Creación de un Stream vacío
Stream<String> emptyStream = Stream.empty();
long val = emptyStream.count();
Suma de arreglo de enteros
int[] numbers = {1, 2, 3, 4, 5, 6, 7};
int sum = Arrays.stream(numbers).sum();
Convertir Stream a List
List<String> abc = Stream.of("a", "b", "c")
.collect(Collectors.toList());
Usando operación count
long count = Stream.of("one").count();
Ejemplo
Usando operación noneMatch
boolean noElementEqualTo5 = IntStream.of(1, 2, 3)
.noneMatch(p -> p == 5);
Usando operación allMatch
List<String> teams = Lists.newArrayList("St. Louis Cardinals Team", "NY Mets Team", "LA Angels Team",
"Washington Nationals Team", "LA Dodgers Team");
boolean containsAL = teams.stream().allMatch(p -> p.contains("Team"));
Ejemplo
Usando forEach(Consumer c)
List<Team> teams = new ArrayList<>();
teams.add(new Team("STL", "St. Louis Cardinals", true, 2011));
teams.add(new Team("NYM", "NY Mets", true, 1986));
teams.add(new Team("LAA", "LA Angels", true, 2002));
teams.add(new Team("WSN", "Washington Nationals", false, 0));
teams.add(new Team("LAD", "LA Dodgers", false, 0));
teams.forEach(p -> System.out.println(p));
Streams de objetos y tipos primitivos
● Java tiene valores primitivos, así como tipos de objetos.
● Para mejorar la eficiencia de Stream tenemos tres Stream de tipos primitivos
○ IntStream, DoubleStream, LongStream
● Pueden usarse junto a los métodos mapToInt(), mapToDouble(),
mapToLong()
Ejemplo
Trabajando con mapToInt(ToIntFunction<T>)
int highScore = students.stream()
.filter(s -> s.graduationYear() == 2015)
.mapToInt(s -> s.getScore())
.max();
OptionalInt oldestYear = teams.stream()
.filter(t -> t.isHasWonWoldSeries())
.mapToInt(Team::getLastTimeWonWorldSeries)
.min();
Method
References
Ejemplo
Trabajando con mapToInt(ToIntFunction<T>)
long totalEquipos = teams.stream()
.filter(t -> t.isHasWonWoldSeries())
.mapToInt(Team::getLastTimeWonWorldSeries)
.count();
Trabajando con mapToDouble(ToDoubleFunction<T>)
List<Transaccion> trxs = ...
//Stream de decimales cuyos elementos son el valor de las transacciones
DoubleStream stream = trxs.stream().mapToDouble(Transaccion::getValor);
Method
References
Nuevos métodos útiles en Java 8
que pueden utilizar Lambdas
Iterable
Iterable.forEach(Consumer c)
Collection
Collection.removeIf(Predicate p)
List
List.replaceAll(UnaryOperator o)
List.sort(Comparator c)
Reemplaza "Collections.sort(List l, Comparator c)"
Ejemplo
Usando Collection.removeIf(Predicate p)
List<Person> personList = new ArrayList<>();
personList.add(new Person("Wilson",35));
personList.add(new Person("Peter",25));
personList.add(new Person("Jones",27));
Usando Predicate como una clase anónima
personList.removeIf(new Predicate<Person>() {
@Override
public boolean test(Person person) {
return "Jones".equals(person.getName());
}
});
Ejemplo
Usando Collection.removeIf(Predicate p)
List<Person> personList = new ArrayList<>();
personList.add(new Person("Wilson",35));
personList.add(new Person("Peter",25));
personList.add(new Person("Jones",27));
Usando Predicate como expresion Lambda.
1.
personList.removeIf((Person person) -> "Jones".equals(person.getName()));
2.
personList.removeIf(person -> "Jones".equals(person.getName()));
Ejemplo
Procesar la siguiente lista para que solamente contenga cadena con letra mayúscula.
Antes de Java 8
List<String> list = Arrays.asList("Alfa", "Bravo", "Charlie", "Delta", "Echo", "Golf");
List<String> listUC=Lists.newArrayList();
for (ListIterator<String> it = list.listIterator(); it.hasNext();) {
listUC.add(it.next().toUpperCase());
}
Usando List.replaceAll(UnaryOperator o)
list.replaceAll(String::toUpperCase);
Method References
Ejemplo
Ordenar la siguiente lista por nombre de personas.
List<Person> personList = new ArrayList<>();
personList.add(new Person("Wilson",35));
personList.add(new Person("Peter",25));
personList.add(new Person("Jones",27));
Antes de Java 8
Collections.sort(personList, new ComparePersonsByName());
class ComparePersonsByName implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.getName().compareTo(p2.getName());
}
}
Ejemplo
Ordenar la siguiente lista por nombre de personas.
List<Person> personList = new ArrayList<>();
personList.add(new Person("Wilson",35));
personList.add(new Person("Peter",25));
personList.add(new Person("Jones",27));
Java 8
Collections.sort(personList, (Person p1, Person p2) -> p1.getName().compareTo(p2.getName()));
Ejemplo
Ordenar la siguiente lista por nombre de personas.
List<Person> personList = new ArrayList<>();
personList.add(new Person("Wilson",35));
personList.add(new Person("Peter",25));
personList.add(new Person("Jones",27));
Java 8
Usando el método por defecto Comparator.comparing
1.
personList.sort(Comparator.comparing((Person p) -> p.getName()));
2.
personList.sort(Comparator.comparing(p -> p.getName()));
Ejemplo
Ordenar la siguiente lista por nombre de personas.
List<Person> personList = new ArrayList<>();
personList.add(new Person("Wilson",35));
personList.add(new Person("Peter",25));
personList.add(new Person("Jones",27));
Java 8
Usando el método por defecto Comparator.comparing y methods references
personList.sort(Comparator.comparing(Person::getName));
Usando import estático
personList.sort(comparing(Person::getName));
Ejemplo
Ordenar la siguiente lista por nombre de personas.
List<Person> personList = new ArrayList<>();
personList.add(new Person("Wilson",35));
personList.add(new Person("Peter",25));
personList.add(new Person("Jones",27));
Java 8
Comparación de dos niveles
personList.sort(Comparator.comparing(Person::getAge).thenComparing(Person::getName));
Usando import estático
personList.sort(comparing(Person::getAge).thenComparing(Person::getName));
methods references
Usando colectores (collectors)
List<String> teamsWithNull = Lists.newArrayList(null, "NY Mets", null,
"Washington Nationals",
"LA Angels", null);
List<String> filterStrings = teamsWithNull
.stream()
.filter(p -> p != null)
.collect(Collectors.toList());
Convertir a un List sin
valores nulos
Usando colectores (collectors)
Antes de Java 8
Map<String, Team> mappedTeams = new HashMap<>();
for (Team team : teams) {
mappedTeams.put(team.getTeamId(), team);
}
Java 8
Map<String, Team> mappedTeams = teams
.stream()
.collect(Collectors.toMap(Team::getTeamId, (p) -> p));
Convertir un List a un
Map
Usando colectores (collectors)
Antes de Java 8
List<RutasPuntos> puntos = ModeloRutas.getInstancia().getPuntoPorRutas(ruta.getIdruta());
Set<Waypoint> waypoints = new HashSet<Waypoint>();
for (RutasPuntos rutasPuntos : puntos) {
searchCriteria.setNameEquals(rutasPuntos.getSector().getDescripcion());
searchCriteria.setMaxRows(1);
ToponymSearchResult searchResult = WebService.search(searchCriteria);
for (Toponym toponym : searchResult.getToponyms()) {
waypoints.add(new Waypoint(toponym.getLatitude(), toponym.getLongitude()));
}
WaypointPainter painter = new WaypointPainter();
painter.setWaypoints(waypoints);
}
Usando colectores (collectors)
Java 8 clase anónima
List<RutasPuntos> puntos = ModeloRutas.getInstancia().getPuntoPorRutas(ruta.getIdruta());
Set<Waypoint> waypoints;
for (RutasPuntos rutasPuntos : puntos) {
searchCriteria.setNameEquals(rutasPuntos.getSector().getDescripcion());
searchCriteria.setMaxRows(1);
ToponymSearchResult searchResult = WebService.search(searchCriteria);
waypoints = searchResult.getToponyms()
.stream()
.map(new Function<Toponym, Waypoint>() {
@Override
public Waypoint apply(Toponym toponym) {
return new Waypoint(toponym.getLatitude(), toponym.getLongitude());
}
})
.collect(Collectors.toSet());
}
Usando colectores (collectors)
Java 8 expresiones lambdas
List<RutasPuntos> puntos = ModeloRutas.getInstancia().getPuntoPorRutas(ruta.getIdruta());
Set<Waypoint> waypoints;
for (RutasPuntos rutasPuntos : puntos) {
searchCriteria.setNameEquals(rutasPuntos.getSector().getDescripcion());
searchCriteria.setMaxRows(1);
ToponymSearchResult searchResult = WebService.search(searchCriteria);
waypoints = searchResult.getToponyms().stream()
.map((Toponym toponym) -> new Waypoint(toponym.getLatitude(), toponym.getLongitude()))
.collect(Collectors.toSet());
}
Depuración (Debugging)
Una forma de hacer depuración de aplicaciones que usen lambas y Streams es usando el método
+peek(Consumer<T>):Stream<T> , el cuál es una operación intermedia y por lo tanto no interrumpe el procesamiento del
Stream.
List<String> newList1 = list
.stream()
.filter(s -> (s.length() % 2)==1)
.map(String::toLowerCase)
.peek(System.out::println)
.collect(Collectors.toList());
Colocar un breakpoint
list
.stream()
.filter(s -> (s.length() % 2)==1)
.map(String::toLowerCase)
.peek(s -> s.toString())
.collect(Collectors.toList());
Depuración(Debugging)
Algunas veces hacer debugging con expresiones lambdas resulta ser un poco tedioso. Las expresiones lambdas no se
compilan como las clases anónimas, sino que son compiladas con llamadas a invokedynamic y su implementación se
hace en tiempo de ejecución.
Una solución alternativa a estos casos es la siguiente:
- Extraer el código de una expresión Lambda en un método separado.
- Sustituir la expresión Lambda con method reference por un nuevo método.
- Establecer puntos de interrupción en las sentencias en el nuevo método.
- Examinar el estado del programa utilizando depurador.
Consejos Prácticos
● Streams pueden ser infinitos, así como finitos. No existe el concepto de
"ruptura" de un Stream. Utilice la operación final (terminal) correspondiente
para detener el procesamiento O utilice el Stream de forma infinita.
● Evite forEach (excepto en casos especiales)
● Necesitas pensar en programación funcional más que programación
imperativa (trate de dejar de pensar en los bucles).
● Piense en la forma de abordar los problemas utilizando recursividad.
¿Preguntas?
¡Gracias por
Acompañarnos!
Referencias
Libros:
Functional Programming in Java (Dr. Venkat Subramaniam)
Enlaces:
http://slidedeck.io/DDuarte/java8-slides
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
https://dzone.com/articles/java-lambda-expressions-basics
http://www.oracle.com/technetwork/es/articles/java/expresiones-lambda-api-stream-java-2633852-esa.html
http://www.oracle.com/technetwork/es/articles/java/expresiones-lambda-api-stream-java-2737544-esa.html
http://www.infoq.com/presentations/java-8-lambda-streams
http://www.infoq.com/articles/Java-8-Lambdas-A-Peek-Under-the-Hood
https://github.com/ecabrerar/java-8-mas-alla-de-las-expresiones-lambda
Código fuente de los ejemplos en GitHub
Asuntos Legales
Todas las marcas registradas, así como todos los
logotipos, imágenes, fotografías, audio y vídeos
mostrados en esta presentación son propiedad de
sus respectivos propietarios y/o representantes.
Su utilización es solamente para fines ilustrativos.
@eudriscabrera
@eudris
@ecabrerar
@eudriscabrera
Eudris Cabrera Rodríguez
Ingeniero Telemático
Desarrollador de Software / Consultor Informático
eudris@gmail.com
https://www.linkedin.com/in/eudriscabrera
http://www.slideshare.net/eudris
https://twitter.com/eudriscabrera
https://github.com/ecabrerar

Weitere ähnliche Inhalte

Ähnlich wie Java 8: Expresiones Lambdas y API Stream BarCamp RD 2016

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 LambdasEudris Cabrera
 
Java 8 - Nuevas características
Java 8 - Nuevas característicasJava 8 - Nuevas características
Java 8 - Nuevas característicasFernando Petrola
 
Presentación Java Evolution - GlobalLogic Club
Presentación Java Evolution - GlobalLogic ClubPresentación Java Evolution - GlobalLogic Club
Presentación Java Evolution - GlobalLogic ClubGlobalLogic Latinoamérica
 
Tutorial en Apache Spark - Clasificando tweets en realtime
Tutorial en Apache Spark - Clasificando tweets en realtimeTutorial en Apache Spark - Clasificando tweets en realtime
Tutorial en Apache Spark - Clasificando tweets en realtimeSocialmetrix
 
Scala en proyectos de vinculación Ancap-UR - 2013-03
Scala en proyectos de vinculación Ancap-UR - 2013-03Scala en proyectos de vinculación Ancap-UR - 2013-03
Scala en proyectos de vinculación Ancap-UR - 2013-03Germán Ferrari
 
SAX (con PHP)
SAX (con PHP)SAX (con PHP)
SAX (con PHP)DaCoom
 
Conceptos fundmentales
Conceptos fundmentalesConceptos fundmentales
Conceptos fundmentalesalondrashare
 
Lambdas y API Stream - Apuntes de Java
Lambdas y API Stream - Apuntes de JavaLambdas y API Stream - Apuntes de Java
Lambdas y API Stream - Apuntes de JavaAlexis Lopez
 
Entrada y salida de datos en java
Entrada y salida de datos en javaEntrada y salida de datos en java
Entrada y salida de datos en javamariasuarezsalazar
 
Aprendiendo AWS Lambda con API Gateway y DynamoDB
Aprendiendo AWS Lambda con API Gateway y DynamoDBAprendiendo AWS Lambda con API Gateway y DynamoDB
Aprendiendo AWS Lambda con API Gateway y DynamoDBAbimael Desales López
 

Ähnlich wie Java 8: Expresiones Lambdas y API Stream BarCamp RD 2016 (20)

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 - Nuevas características
Java 8 - Nuevas característicasJava 8 - Nuevas características
Java 8 - Nuevas características
 
Java 8
Java 8Java 8
Java 8
 
Un vistazo a java 8
Un vistazo a java 8Un vistazo a java 8
Un vistazo a java 8
 
Java Lambda
Java LambdaJava Lambda
Java Lambda
 
Presentación Java Evolution - GlobalLogic Club
Presentación Java Evolution - GlobalLogic ClubPresentación Java Evolution - GlobalLogic Club
Presentación Java Evolution - GlobalLogic Club
 
Tutorial en Apache Spark - Clasificando tweets en realtime
Tutorial en Apache Spark - Clasificando tweets en realtimeTutorial en Apache Spark - Clasificando tweets en realtime
Tutorial en Apache Spark - Clasificando tweets en realtime
 
Scala en proyectos de vinculación Ancap-UR - 2013-03
Scala en proyectos de vinculación Ancap-UR - 2013-03Scala en proyectos de vinculación Ancap-UR - 2013-03
Scala en proyectos de vinculación Ancap-UR - 2013-03
 
SAX (con PHP)
SAX (con PHP)SAX (con PHP)
SAX (con PHP)
 
Grupo1
Grupo1Grupo1
Grupo1
 
Django y Python para todos
Django y Python para todosDjango y Python para todos
Django y Python para todos
 
Conceptos fundmentales
Conceptos fundmentalesConceptos fundmentales
Conceptos fundmentales
 
MapReduce
MapReduceMapReduce
MapReduce
 
Computacion3
Computacion3Computacion3
Computacion3
 
Computacion3
Computacion3Computacion3
Computacion3
 
Java - No numérica - II
Java - No numérica - IIJava - No numérica - II
Java - No numérica - II
 
Lambdas y API Stream - Apuntes de Java
Lambdas y API Stream - Apuntes de JavaLambdas y API Stream - Apuntes de Java
Lambdas y API Stream - Apuntes de Java
 
Curso Java Avanzado 3 Js Ps
Curso Java Avanzado   3 Js PsCurso Java Avanzado   3 Js Ps
Curso Java Avanzado 3 Js Ps
 
Entrada y salida de datos en java
Entrada y salida de datos en javaEntrada y salida de datos en java
Entrada y salida de datos en java
 
Aprendiendo AWS Lambda con API Gateway y DynamoDB
Aprendiendo AWS Lambda con API Gateway y DynamoDBAprendiendo AWS Lambda con API Gateway y DynamoDB
Aprendiendo AWS Lambda con API Gateway y DynamoDB
 

Kürzlich hochgeladen

EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxJorgeParada26
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estossgonzalezp1
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanamcerpam
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxAlan779941
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.FlorenciaCattelani
 
Guia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos BasicosGuia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos BasicosJhonJairoRodriguezCe
 
investigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIinvestigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIhmpuellon
 
Buenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxBuenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxFederico Castellari
 
redes informaticas en una oficina administrativa
redes informaticas en una oficina administrativaredes informaticas en una oficina administrativa
redes informaticas en una oficina administrativanicho110
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21mariacbr99
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...JohnRamos830530
 

Kürzlich hochgeladen (11)

EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estos
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvana
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.
 
Guia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos BasicosGuia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos Basicos
 
investigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIinvestigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXI
 
Buenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxBuenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptx
 
redes informaticas en una oficina administrativa
redes informaticas en una oficina administrativaredes informaticas en una oficina administrativa
redes informaticas en una oficina administrativa
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
 

Java 8: Expresiones Lambdas y API Stream BarCamp RD 2016

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