Ponentes:
Ignacio Molina Cuquerella
Héctor Pardo González
Java 8
Time to join the Future
Empieza el viaje
1. Time
2. Functional Programming
3. Optionals
4. Collection Streams
5. Concurrency
Time
Java 8 :: Time
Clock
La clase Clock aparece para reducir el uso de métodos estáticos
y facilitar el desarrollo de pruebas en casos donde es necesario
trabajar con la fecha y hora actuales
• Dependencia inyectable
• Métodos factoría
• Abstracta
• Múltiples implementaciones
• SystemClock, TickClock, FixedClock, OffsetClock
Java 8 :: Time
DateTime
• Basado en la biblioteca Joda-Time
• Surge por la necesidad de tener una conciencia global de la hora
• Un tipo de precisión diferente según la necesidad
• ZonedDateTime, OffsetDateTime, LocalDateTime, y más
• Inmutable
• Compatible con Clock
ZonedDateTime date = [Link](clock)
• Operaciones con TemporalAmount
• Parser personalizable mediante DateTimeFormatter
Java 8 :: Time
Units - TemporalAmount
Duration Period
• Permite manejar distintas • Pensado para manejar
magnitudes de tiempo de unidades de tiempo más
tipo exacto (horas, minutos, abstractas (años, meses,
segundos, etc) semanas, etc)
• Basada en segundos y • Para operar con fechas
nanosegundos • Basada en años, meses y
días
Pero hay más…
GitHub repository:
[Link]
Bajemos a ver un poco
de código...
Functional
Programming
Java 8 :: Functional Programming
Definición y características
• Es un paradigma de la programación declarativa basado en el uso de funciones
matemáticas.
• Tiene sus raíces en el cálculo lambda.
• No hay efectos colaterales: el valor generado por una función depende exclusivamente
de los argumentos pasados a la función.
• No hay mutabilidad en variables.
• Funciones de primera clase: las funciones se tratan como objetos con el
comportamiento que ello conlleva, eg. ser almacenadas en una variable.
Function<Integer, Integer> addTwo = value -> value + 2
• Funciones de orden superior: son funciones que pueden tomar otras funciones como
argumentos o devolverlos como resultados.
int myMethod(Function<Integer,Integer> f)
Java 8 :: Functional Programming
Interfaz funcional y expresión lambda
• Una interfaz funcional es aquella interfaz que sólo define un método abstracto.
• Se define con la anotación @FunctionalInterface
• Se puede expresar mediante una expresión lambda.
• Ejemplo:
λ expression
Java 8 :: Functional Programming
Programación
Imperativa
Define un algoritmo en el que se
describen los pasos necesarios
para solucionar un problema.
Programación
Funcional
Se describe el problema que se
quiere solucionar mediante
funciones sin efectos
colaterales.
Java 8 :: Functional Programming
Ejemplos
[Link]
Interfaz Funcional Propósito Expresión Lambda
Consumer<T> Operación que acepta un argumento y no devuelve ningún resultado x -> { }
Function<T, R> Operación que acepta un argumento y produce un resultado x -> y
Predicate<T> Operación que acepta un argumento y devuelve true/false x -> true
Supplier<T> Operación que no acepta argumentos y proporciona un resultado () -> x
BiFunction<T, U, R> Operación que devuelve un resultado a partir de dos argumentos (x, y) -> z
BiPredicate<T, U> Operación que acepta dos argumentos y devuelve true/false (x, y) -> false
... ... ...
GitHub repository:
[Link]
Bajemos a ver un poco
de código...
Porque hay cosas
que pueden ir
mal...
Optionals
Java 8 :: Optional
Qué son y por qué usarlos opcionales
• Te salvan de situaciones con null
• [Link] es más versátil que null
• Interfaz fluida
• Utiliza el nuevo paradigma funcional
• Facilita evitar la divergencia de flujos en distintas ramas
• Falla rápido (null ó empty)
Java 8 :: Optional
Cuándo
SÍ
• Cuando tengas la tentación de devolver un null
• Cuando quieras operar con un campo que pueda no existir
NO
• Como parámetros
• Dentro de estructuras de datos (Colecciones)
• Como dato a serializar
• Como atributo de clase
Java 8 :: Optional
[Link]<T>
Método Estático Función Estado Descripción
of Sí - Creación Crea un nuevo opcional lanza excepción si está vacío
ofNullable Sí - Creación Crea un nuevo opcional
empty Sí - Creación Crea un opcional que siempre será vacío
filter No Predicate Intermedio Elimina el contenido que no cumpla el predicado
map No Function Intermedio Transforma el contenido
flatMap No Function Intermedio Ataja una indirección de optionales
isPresent No - Final Nos dice si existe un contenido
ifPresent No Consumer Final Ejecuta un bloque usando el contenido
get No - Final Devuelve el contenido o en su defecto lanza una excepción
orElse No - Final Devuelve el contenido o en su defecto el valor dado
orElseGet No Supplier Final Devuelve el contenido del opcional o en su defecto del bloque dado
orElseThrow No Supplier Final Devuelve el contenido o lanza la excepción especificada
GitHub repository:
[Link]
Bajemos a ver un poco
de código...
Collection
Streams
Java 8 :: Collection Streams
Definición y características I
• Clase principal: Stream<T> perteneciente a [Link]. Se compone de tres elementos:
1. Fuente de datos.
2. Operaciones intermedias.
3. Operación final.
• Tipos de operaciones:
• Intermedias: filter(), map(), distinct(), skip(), limit(), ...
• Finales: collect(), reduce(), findAny(), noneMatch(), count(), …
• Las operaciones intermedias son perezosas: sólo se invocarán si se ejecuta una
operación final y siempre en el orden definido. El pipeline de operaciones se ejecutará
completo para cada elemento.
Java 8 :: Collection Streams
Definición y características II
• Iteración interna vs iteración externa del paradigma imperativo.
• Ejecutar una operación final hace al stream inaccesible y no podrá ser reutilizado:
Java 8 :: Collection Streams
Invocación perezosa
¿Cuántos logs veremos por pantalla?
Java 8 :: Collection Streams
Ejemplo Java 7 vs Java 8
GitHub repository:
[Link]
Bajemos a ver un poco
de código...
Concurrency
Java 8 :: Concurrency
CompletionStage
• Trabajo asíncrono (No bloqueante)
• CompletableFuture es la implementación de referencia
• Permite trabajar de una forma sencilla con futuros
• Es soportado en frameworks asíncronos
• Play Framework versión 2
• Spring Boot versión 2
• Probablemente más...
Java 8 :: Concurrency
Metodos más utilizados
[Link]<T>
Método Estático Función Productor Descripción
runAsync Sí Runnable No Crea un nuevo completable y comienza a ejecutar el trabajo
supplyAsync Sí Supplier Si Crea un nuevo completable y comienza el trabajo
thenApply No Function Si Transforma el resultado de un completable mediante otro
thenAccept No Consumer No Realiza una tarea a partir del resultado de dos completables
thenCompose No Function Si Asimila un completable producido a partir de otro
thenCombine No BiFunction Si Transforma el contenido de dos completables en uno nuevo
exceptionally No Function Si Ejecuta una tarea cuando el completable termine de forma excepcional
Java 8 :: Concurrency
Otros metodos
[Link]<T>
Método Estático Función Productor Descripción
runAfterBoth No Runnable No Realiza una tarea cuando ambos completables terminan
thenAcceptBoth No BiConsumer No Realiza una tarea a partir del resultado de dos completables
runAfterEither No Runnable No Realiza una tarea cuando alguno de los dos completables termina
applyToEither No Function Si Transforma el resultado del primer completable en terminar
acceptEither No Consumer No Realiza una tarea a partir del primer completable que termine
whenComplete No BiConsumer No Realiza una tarea cuando el completable termine aunque lo haga de forma
excepcional, no altera el resultado
handle No BiFunction Si Ejecuta una tarea cuando el completable termine aunque lo haga de forma
excepcional
Java 8 :: Concurrency
Y más… CompletableFuture
Todos los métodos anteriores permiten realizar una correcta
sincronización, sin tener que forzar en ningún momento bloqueo
del hilo de ejecución, mediante el encadenando de tareas
asíncronas. Pero pueden ser algo engorrosas cuando
dependemos del resultado de muchas tareas.
anyOf allOf
• Acepta un array de completables • Acepta un array de completables
• Realiza una tarea cuando alguna • Realiza una tarea cuando todas
de las anteriores se ha las anteriores se han
completado completado
Java 8 :: Concurrency
Callbacks
La clase CompletableFuture permite ser utilizada como callback
mediante la instanciación como incompleto.
CompletableFuture<T> promise = new CompletableFuture<>();
Que en un futuro será completado.
[Link](result);
Java 8 :: Concurrency
Executors
Los métodos definidos por CompletionStage tienen una versión
alternativa mediante sobrecarga que permite establecer un pool
de hilos para ejecutar las tareas.
Normalmente a estos métodos se les distingue porque el nombre
termina por Async y aceptan un Executor.
<U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn) -> conserva el pool
<U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn) -> ForkJoin
<U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
GitHub repository:
[Link]
Bajemos a ver un poco
de código...
The road so far…
● Time
● Functional Programming
● Optionals
● Collection Streams
● Concurrency
GitHub repository:
[Link]
Ponentes:
Ignacio Molina Cuquerella - imolina@[Link]
Héctor Pardo González - hpardo@[Link]
¿Eres capaz de interpretar esta expresión?
() -> () -> “Hello World!”
¿Sabrías decirme qué hace este bloque de
código?
Map<String, List<String>> map = generateMap();
[Link]()
.stream()
.map(entry -> [Link]()
.stream()
.map(value -> new String[] { [Link](), value })
.flatMap(Arrays::stream))
.flatMap([Link]())
.toArray(String[]::new);
¡Vente a descubrirlo!