Vale la pena recordar que Opcional se debe usar para información que se retorna, en lugar de información que se recibe (a través de parámetros, por ejemplo). Corregirme si me equivoco.
Introducción a la programación Funcional
¿Qué es la Programación Funcional?
Entendiendo las partes de la programación funcional
¿Qué es una función en Java?
Funciones como ciudadanos de primera clase
Funciones puras
Entendiendo los efectos secundarios
Funciones de orden mayor
Funciones lambda
Inmutabilidad
Functional Programming en Java
Repositorio del curso
Configuración del entorno de trabajo
Revisando el paquete java.util.function: Function
Revisando el paquete java.util.function: Predicate
Revisando el paquete java.util.function: Consumer y Supplier
Revisando el paquete java.util.function: Operators y BiFunction
Entendiendo dos jugadores clave: SAM y FunctionalInterface
Operador de Referencia
Analizando la inferencia de tipos
Comprendiendo la sintaxis de las funciones lambda
Usando metodos default en nuestras interfaces
Dándole nombre a un viejo amigo: Chaining
Entendiendo la composición de funciones
Optional y Streams: Datos mas interesantes
La clase Optional
Entendiendo los Streams
¿Qué son los Stream listeners?
Operaciones y Collectors
Streams de tipo específico y Paralelismo
Operaciones Terminales
Operaciones Intermedias
Collectors
Todo junto: Proyecto Job-search
job-search: Un proyecto para encontrar trabajo
Vista rápida a un proyecto de Gradle
Revisando las opciones para nuestro CLI
Librerías adicionales para nuestro proyecto
Entendiendo la API de jobs
Diseñando las Funciones Constructoras de nuestro Proyecto
Agregando validaciones de datos
Diseñando las funciones de transformacion de datos
Creando flujos extras de transformación de Datos
Conclusiones
Un repaso a lo aprendido
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Sinuhé Jaime Valencia
Aportes 23
Preguntas 10
Vale la pena recordar que Opcional se debe usar para información que se retorna, en lugar de información que se recibe (a través de parámetros, por ejemplo). Corregirme si me equivoco.
Pensé que esta clase era Opcional , que se podía ver o no, ajajajjaajjaaj
⠀
La clase Optional
permite encapsular un dato del cual no se tiene certeza de su valor, evitando la utilización de valores null
, excepciones NullPointerException
y la repetición de verificaciones de tipo dato != null
.
⠀
Esta clase además provee métodos que pueden ser usados para manejar el dato dentro del Optional
, o para contemplar los casos cuando el dato no está presente. Dependiendo del caso estos métodos pueden recibir un Function
, Consumer
, Supplier
, etc.
⠀
Por ejemplo, la función getPersona
carga desde la base de datos una Persona
y la devuelve dentro de un Optional<Persona>
.
public Optional<Persona> getPersona(int id) {
Persona p = database.get(id);
if (p == null) {
return Optional.empty();
} else {
return Optional.of(p);
}
// También podría retornarse Optional.ofNullable(p);
}
Una forma de utilizar el Optional
devuelto sería:
Optional<Persona> personaOptional = getPersona(45);
// Si existe la Persona, muestra nombr ey apellido
if (personaOptional.isPresent()) {
System.out.println(personaOptional.get().getNombre() + " " + perpersonaOptionalsona.get().getApellido());
}
// Lo mismo utilizando Lambda
personaOptional.ifPresent(p -> System.out.println(p.getNombre() + " " + p.getApellido()));
// Lo mismo mapeando a un String con un mensaje en caso de que no exista la Persona
String texto = persona.map(p -> p.getNombre() + " " + p.getApellido())
.orElse(() -> "No existe");
System.out.println(texto);
// Extrae la Persona dentro del Optional si está presente, de lo contrario, asigna una nueva instancia por defecto
Persona persona = personaOptional.orElse(new Persona());
Me parece excelente, muchos métodos y usos aunque tuve que ir a la Api de Java para extender la explicación ya que aquí solo los mencionas por encima, pero definitivamente muy útil la clase. Gracias.
Posdata: les recomiendo ir a la Api también. saludos.
RESUMEN
La clase Optional es una manera de almacenar un dato del cual no tenemos certeza cuál es el valor, si está o no está presente, y poder acceder a este dato mediante operadores (funciones, consumers, suppliers) que cuando esté presente el dato, la clase Optional va a invocar esas funciones pasándoles el dato, en caso contrario (por ejemplo el caso de null) la clase Optional no va a invocar dichas funciones.
Internamente Optional estará haciendo la lógica para saber cuándo sí y cuándo no ejecutar un pedazo de código.
Un ejemplo de la clase aplicada.
public class Optional_2 {
private static void threeDigitNonFunctional(Integer data) {
Optional<Integer> dataOptional = Optional.ofNullable(data);
if (dataOptional.isPresent()) {
Integer num = dataOptional.get();
String string = "" + num;
if (string.length() == 3) {
System.out.println(string);
}
}
}
private static void threeDigitFuctional(Integer data) {
Optional<Integer> dataOptional = Optional.ofNullable(data);
dataOptional
.map(num -> "" + num)
.filter(s -> s.length() == 3)
.ifPresent(System.out::println);
}
public static void main(String[] args) {
threeDigitNonFunctional(587);
threeDigitFuctional(687);
threeDigitNonFunctional(null);
threeDigitFuctional(null);
}
}
Optional
Genial 😃 muy útil
Genial.
La verdad es que el flatMap no me ha quedado nada claro…
Hubiera estado bien algún ejemplo.
Esta clase va ser muy útil para los casos en que la aplicación tenga funciones donde los datos sean nulos o no estén presentes. Muchas gracias por la explicación instructor Sinuhé.
Para mi fue un poco densa la clase, pero luego de detenerme a digerir el contenido esto esta super util.
Collection.emptyList();
Excelente clase!
El método flatMap() recibe por parámetro una función (lambda) que ejecuta ciertas instrucciones (según lo que especifique el programador) y que, y ésta es la parte importante, retorna un objeto de tipo Optional<T> (esto es obligatorio, si no, no compila), donde T es un tipo de dato que se especifica en el bloque de código (la lambda) que se pasa como argumento a flatMap(). Cabe resaltar que el input de esta lambda es uno solo, y éste es automáticamente el valor que el optional sobre el que se está ejecutando el flatMap() encapsula, si es que existe, esto mismo lo hace null safe, porque si es null, es decir, que el optional está vacío, entonces no ejecuta nada. También está el caso en que T es un tipo Optional en sí (de hecho este es el caso de uso más común), en este caso solo se debe retornar el dato de tipo T.
Class option controla el return Null
Otra cosa importante a considerar es que Optional#isPresent
(y otros métodos) le agregan un overhead, la mayoría de veces insignificante, pero que es interesante saber.
Noten el siguiente código:
public class Main {
public static void main(String[] args) {
Optional<String> optional = Optional.of("Java 8");
optional.ifPresent(Main::uno);
}
public static void uno(String str) {
Optional<String> optional = Optional.of(str + ", Java 9");
optional.ifPresent(Main::dos);
}
public static void dos(String str) {
Optional<String> optional = Optional.of(str + ", Java 10");
optional.ifPresent(Main::tres);
}
public static void tres(String str) {
Optional<String> optional = Optional.of(str + ", Java 11");
optional.ifPresent(s -> new Exception().printStackTrace());
}
}
En el stack tendremos tres stack frames correspondientes a las llamadas a uno()
, dos()
, tres()
, pero aparte cada una de esas llamadas se hacen mediante isPresent()
, entonces hay que sumar otros 3 stack frames, y luego aparte hay que sumarle otros 3 por la invocación a accept()
hecha dentro de la implementación de isPresent()
(ver abajo). Agregaría un screenshot de los frames pero no sé cómo subirlo, need help (no quiero subir la imagen a servicios de terceros). Igual si lo ejecutan al final deben de ver el stacktrace.
Así en total tenemos ~9 entradas en el stack. Si no usaramos el isPresent()
ese número se reduciría. Esto no quiere decir que es mejor no usar isPresent()
porque seguramente es más lo que ganamos al usarlo (el código es más legible, mantenible y se hace más rápido) que lo que ganamos al no usarlo (diminutas diferencias en el performance).
public void ifPresent(Consumer<? super T> action) {
if (value != null) {
action.accept(value);
}
}
👆 Implementación de JDK para Optional#isPresent()
Excelente explicacion de los Optional.
Hice este ejemplo por si a alguien mas le resulta util.
public class Optional2 {
public static void main(String[] args) {
ArrayList<String> listaNombres = new ArrayList<>();
listaNombres.add(0, "Persona 1");
listaNombres.add(1, "Persona 2");
listaNombres.add(2, "Persona 3");
Optional<ArrayList<String>> validarLista = validarAlgo(null);
// Optional<ArrayList<String>> validarLista = validarAlgo(listaNombres);
if (validarLista.isPresent()){
System.out.println("si esta presente");
}else {
System.out.println("Optional no esta presente");
}
// validarLista.ifPresent(strings -> {
// System.out.println("si esta presente");
// strings.forEach(System.out::println);
// });
}
static Optional<ArrayList<String>> validarAlgo(ArrayList lista){
try {
System.out.println("Ejecutamos el proceso del try");
return Optional.ofNullable(lista);
}catch (IndexOutOfBoundsException exception){
System.out.println("atrapamos excepcion");
return Optional.empty();
}
}
}
Si eh llegado a entender, pero, hay muchos defectos en este curso, esta demasiado desordenado, usa metodos que creo fuera de la clase, para usarlos como ejemplo, que le cuesta volverlos a crear para entenderlo, esta muy desordenado
✅
Para un mejor entendimiento, podríamos decir que Optional almacena dos valores, por un lado con datos y por otro lado los que no tienen datos, y podemos usarlo a nuestro antojo 😄
El profe es muy bueno, pero en esta clase al no partir de un ejemplo claro llega un momento en que te pierdes.
Yo porque entiendo de antes los Optional pero entiendo que el que no lo haya visto se tenga que ver este vídeo a 0.5x varias veces para comprenderlo.
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?