La programación funcional ha revolucionado la manera en que desarrollamos software, haciendo el código más limpio y eficiente. En el contexto de Java, la programación funcional se refuerza con múltiples elementos como funciones, métodos, predicados, y "consumidores". Estos componentes simplifican el proceso de programación, pero un elemento clave que introduce Java 8 es la clase Optional. Este componente no solo mejora la programación funcional sino que también previene errores comunes como el NullPointerException, al permitir manejar de forma explícita la ausencia de valores.
¿Cómo manejar valores inexistentes con Optional?
Cuando desarrollamos, enfrentamos situaciones en las que métodos deben retornar datos como listas o strings. En Java, la práctica común es retornar una colección vacía en vez de null. Sin embargo, cuando se trata de otros tipos de datos, como enteros, los problemas se multiplican. A menudo, se optaba por retornar valores "degenerados" como 0 o -1, pero esto podría llevar a confusiones y errores.
Es aquí cuando la clase Optional entra en juego. Optional actúa como un contenedor que puede o no contener un valor. Si hay un dato presente, podemos operar sobre él; si no lo hay, podemos definir un valor por defecto. De esa manera, evitamos manipulaciones directas con datos nulos que puedan generar errores imprevistos.
Ejemplo de uso de Optional
Para ilustrar el uso de Optional, consideremos un método que busca nombres:
En este ejemplo, optionalName evalúa si el dato está presente; si lo está, imprime el nombre. Esto elimina la dependencia de checks explícitos contra null, haciendo el código más limpio y legible.
Operaciones avanzadas con Optional
Optional no solo sirve para chequeos básicos; también facilita operaciones más complejas y elegantes en el contexto de programación funcional:
Mapeo y conversión de datos: Permite transformar el valor contenido en un Optional sin necesidad de validaciones constantes. Por ejemplo:
El uso de la clase Optional en Java no solo incrementa la seguridad al evitar errores de tipo NullPointerException, sino que también promueve un estilo de programación más declarativo y legible, lo que puede ser crucial en grandes proyectos donde la consistencia del manejo de valores es fundamental. Abrazar Optional es un paso hacia la adopción de programaciones más funcionales y elegantes, y te ayudará a escribir código más robusto y mantenible.
Recuerda, cada herramienta en programación tiene su lugar y función. Te animamos a seguir explorando las potencialidades que Optional y otras clases funcionales ofrecen, para asegurar que tu código no solo funcione sino que sea eficiente y sostenible a largo plazo. La programación es un viaje constante de aprendizaje y mejora. ¡Adelante!
Uso de la Clase Optional en Java para Manejo de Valores Nulos
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.
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.
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.
me gastaría que pudiéramos entrar mas a fondo en cuando usar orelse y orelseGet asi como of y ofNullable, son dos cosas que a veces me lían un poco, por cierto, excelente el curso, tiene planeado algún curso de rxjava?
Es buena practica cuando tu atributo es una referencia a otra entidad o a una lista de entidades que podrian no existir dada un filtro en una consulta. un caso tipico es tratar de acceder a un registro en donde el ID es inexistente, considerando ese caso debes usar Optional pero a nivel de Objetos en vez de atributos.
Quiero agradecer por esta lección sobre MapStruct. La explicación fue clara, directa y muy agradable. Me ayudó a entender cómo usar esta herramienta para mapear objetos de manera eficiente.
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é.
Optional
⠀
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>.
publicOptional<Persona>getPersona(int id){Persona p = database.get(id);if(p ==null){returnOptional.empty();}else{returnOptional.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 apellidoif(personaOptional.isPresent()){System.out.println(personaOptional.get().getNombre()+" "+ perpersonaOptionalsona.get().getApellido());}// Lo mismo utilizando LambdapersonaOptional.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 PersonaString 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 defectoPersona persona = personaOptional.orElse(newPersona());
La diferencia esta en como trabajan de forma interna el opcional. El método flatMap al declarar que recibe un Opcional en su firma, por defecto elimina el Optinal que se encuentre más a la derecha. Por su parte el método map no hace esto.
Esto parece un poco enredado de entender, por eso te dejo 2 ejemplos, que espero te aclaren un poco el panorama
Optional<String> nombre =Optional.of("Pepe");System.out.println("Map "+ nombre.map(x ->{System.out.println(x);return x;// Diferencia}));System.out.println("flatMap : "+ nombre.flatMap( x ->{System.out.println(x);returnOptional.of(x);})// Diferencia);