En Java 8, tenemos un archivo Optional
clase en java.util
paquete. Esta clase se introduce para evitar NullPointerException que a menudo encontramos si no realizamos comprobaciones nulas en nuestro código. Usando esta clase podemos verificar fácilmente si una variable tiene un valor nulo o no y al hacerlo podemos evitar la NullPointerException. En esta guía veremos cómo trabajar con la clase opcional y cómo utilizar los distintos métodos de esta clase.
Antes de mirar el ejemplo de la clase opcional, veamos qué sucede cuando no usamos la clase opcional y hacemos la verificación nula.
Ejemplo de Java: sin usar la clase opcional
En este ejemplo, no hemos asignado el valor a String str y estamos intentando extraer la subcadena de él. Como no hay ningún valor en str, el programa lanza NullPointerException.
public class Example { public static void main(String[] args) { String[] str = new String[10]; //Getting the substring String str2 = str[9].substring(2, 5); //Displaying substring System.out.print(str2); } }
Producción:
Exception in thread "main" java.lang.NullPointerException at Example.main(Example.java:5)
Solución: usar la clase opcional
Optional.ofNullable()
de clase Opcional, devuelve un Opcional no vacío si el objeto dado tiene un valor; de lo contrario, devuelve un Opcional vacío.
Podemos verificar si el valor devuelto opcional está vacío o no está vacío usando el isPresent()
método.
//Importing Optional class import java.util.Optional; public class Example { public static void main(String[] args) { String[] str = new String[10]; Optional<String> isNull = Optional.ofNullable(str[9]); if(isNull.isPresent()){ //Getting the substring String str2 = str[9].substring(2, 5); //Displaying substring System.out.print("Substring is: "+ str2); } else{ System.out.println("Cannot get the substring from an empty string"); } str[9] = "AgraIsCool"; Optional<String> isNull2 = Optional.ofNullable(str[9]); if(isNull2.isPresent()){ //Getting the substring String str2 = str[9].substring(2, 5); //Displaying substring System.out.print("Substring is: "+ str2); } else{ System.out.println("Cannot get the substring from an empty string"); } } }
Producción:
Cannot get the substring from an empty string Substring is: raI
Ejemplo: métodos opcionales isPresent () vs ifPresent ()
En el ejemplo anterior, lo vimos usando isPresent()
podemos verificar si el objeto opcional particular (o instancia) está vacío o no está vacío.
Hay otro método presente en la clase Opcional, que solo se ejecuta si el objeto opcional especificado no está vacío, el método es ifPresent()
. Veamos un ejemplo para entender la diferencia.
//Importing Optional class import java.util.Optional; public class Example { public static void main(String[] args) { //Creating Optional object from a String Optional<String> GOT = Optional.of("Game of Thrones"); //Optional.empty() creates an empty Optional object Optional<String> nothing = Optional.empty(); /* isPresent() method: Checks whether the given Optional * Object is empty or not. */ if (GOT.isPresent()) { System.out.println("Watching Game of Thrones"); } else { System.out.println("I am getting Bored"); } /* ifPresent() method: It executes only if the given Optional * object is non-empty. */ //This will print as the GOT is non-empty GOT.ifPresent(s -> System.out.println("Watching GOT is fun!")); //This will not print as the nothing is empty nothing.ifPresent(s -> System.out.println("I prefer getting bored")); } }
Producción:
Watching Game of Thrones Watching GOT is fun!
Java 8: métodos opcionales orElse () y orElseGet ()
Estos dos métodos orElse () y orElseGet () devuelven el valor del objeto opcional si no está vacío, si el objeto está vacío, devuelve el valor predeterminado pasado a este método como argumento.
//Importing Optional class import java.util.Optional; public class Example { public static void main(String[] args) { //Creating Optional object from a String Optional<String> GOT = Optional.of("Game of Thrones"); //Optional.empty() creates an empty Optional object Optional<String> nothing = Optional.empty(); //orElse() method System.out.println(GOT.orElse("Default Value")); System.out.println(nothing.orElse("Default Value")); //orElseGet() method System.out.println(GOT.orElseGet(() -> "Default Value")); System.out.println(nothing.orElseGet(() -> "Default Value")); } }
Producción:
Game of Thrones Default Value Game of Thrones Default Value
Java 8 – Optional.map y Optional.flatMap
En este ejemplo, veremos cómo funciona Optional con map y flatMap.
//Importing Optional class import java.util.Optional; public class Example { public static void main(String[] args) { //Creating Optional object from a String Optional<String> GOT = Optional.of("Game of Thrones"); //Optional.empty() creates an empty Optional object Optional<String> nothing = Optional.empty(); System.out.println(GOT.map(String::toLowerCase)); System.out.println(nothing.map(String::toLowerCase)); Optional<Optional<String>> anotherOptional = Optional.of(Optional.of("BreakingBad")); System.out.println("Value of Optional object"+anotherOptional); System.out.println("Optional.map: " +anotherOptional.map(gender -> gender.map(String::toUpperCase))); //Optional<Optional<String>> -> flatMap -> Optional<String> System.out.println("Optional.flatMap: " +anotherOptional.flatMap(gender -> gender.map(String::toUpperCase))); } }
Producción:
Optional[game of thrones] Optional.empty Value of Optional objectOptional[Optional[BreakingBad]] Optional.map: Optional[Optional[BREAKINGBAD]] Optional.flatMap: Optional[BREAKINGBAD]
Ejemplo: opcional con filtro
En este ejemplo, veremos cómo funciona Opcional con el filtro. Para leer los filtros, consulte esta guía: Filtros de Java.
Más tutoriales de filtros:
- Java: filtrar un mapa
- Filtrar valores nulos de una secuencia en Java
//Importing Optional class import java.util.Optional; public class Example { public static void main(String[] args) { //Creating Optional object from a String Optional<String> GOT = Optional.of("Game of Thrones"); /* Filter returns an empty Optional instance if the output doesn't * contain any value, else it returns the Optional object of the * given value. */ System.out.println(GOT.filter(s -> s.equals("GAME OF THRONES"))); System.out.println(GOT.filter(s -> s.equalsIgnoreCase("GAME OF THRONES"))); } }
Producción:
Optional.empty Optional[Game of Thrones]
Referencias:
Java 8 – clase opcional JavaDoc