Está en la página 1de 13

Optional

Optional
• En Java 8 se introdujeron los Optionals para modelizar la
posibilidad de ausencia de valor en un tipo de dato,
principalmente en el caso del valor retornado por un método.

• Ahora que disponemos de los Optionals deberíamos evitar


devolver el valor null en un método.

• Sabemos que acceder a una referencia cuyo valor es null


produce la excepción NullPointerException. Sin
embargo, acceder a un Optional que contenga un null
produce la excepción NoSuchElementException.
Entonces, ¿dónde está la ventaja?

2
Optional

• Una persona puede tener un coche, un coche puede tener un seguro


• Pero no toda persona tiene coche, por lo que hacemos que el método
getCar() de Person devuelva un tipo Optional.
• Esto es interesante porque estamos forzando a quien tenga que utilizar el
método getCar() a tomar consciencia de que puede ser que no haya
coche.
• Estamos evitando una futura NullPointerException. 3
Optional

• El siguiente método devuelve el nombre de la compañía de


seguros del coche de una determinada persona.
• Funcionamiento:
– Llamamos al método getInsurance() de un coche y éste
nos retorna un Optional.
– Invocamos al método isPresent() del Optional y
obtenemos un boolean.
– Si el valor obtenido es true, entonces es que el seguro tiene
nombre y lo devolvemos; si es false entonces devolvemos la
cadena “Unknown insurance”.

4
Optional

• Lo que realmente sucede aquí es que este código es en la


práctica el mismo código que teníamos antes de Java 8, lo
que en lugar de preguntar por el valor null estamos
preguntando si isPresent().

• Por tanto este código no tiene mucho interés.

5
Optional

• En cambio, si utilizamos el método map() de la clase


Optional, sí que obtenemos una mejora real respecto al
uso de null.

• map() recibe un método como parámetro, el cual solo será


ejecutado en caso de que el insurance (que es un
Optional) no esté vacío.

• Sin embargo, si finalmente el Optional está vacío, ¿cómo


podemos devolver una cadena por defecto?
6
Optional

• Gracias a que Optional presenta un API fluida, podemos


encadenar la llamada a map() con el método orElse().

• Hay que tener en cuenta que lo que le pasemos al método


orElse() va a ser evaluado siempre.

• Este hecho es determinante si el argumento de orElse()


consume muchos recursos o tarda mucho en ser ejecutado
(por ejemplo una llamada a un Web Service).

7
Optional

• Optional dispone del método orElseGet(), que la


versión lazy del método orElse().

• El método orElseGet() solamente se evalúa si el


Optional está vacío.

• Por tanto, este es el método que deberíamos usar en la


mayoría de las situaciones.

8
Optional

• La tabla siguiente muestra los métodos que se añadieron a


Optional en Java 9

9
Optional

• Retomando el modelo de datos previo: supongamos que


necesitamos implementar un método que dada una lista de
personas retorna los nombres de las compañías de sus
respectivos seguros de coche.

10
Optional

• Tendríamos un método de este tipo:


– A partir de la lista de personas devolvemos un Set con los nombres de las compañías de
seguros.
– Para ello se hace un recorrido por la lista de personas y por cada una se llama al método
getCar(), el cual retorna un Stream de Optional<Car>.
– Por cada Optional<Car> devuelto se llama al método getInsurance(), el cual retorna
un Stream de Optional<Insurance>.
– Por cada Optional<Insurance> devuelto se llama al método getName(), el cual retorna
un Stream de Optional<String>.
– Entonces generamos un Set<Optional<String>>.
– Finalmente, hemos de filtrar para quedarnos solo con los Optional no vacíos, extraer con
get() los valores y generar un Set<String>. 11
Optional

• Nos podemos ahorrar toda la parte anteriormente vista del


final.
• Para ello, si una vez que tenemos un Optional<String>
con los nombres de las compañías, llamamos a flatMap()
pasando como argumento Optional::stream,
obtendremos un Stream<Optional<String>> donde todos
los elementos tienen valor, y ya es inmediato generar el
Set<String>.
12
Optional
• Hay una serie de antipatrones con Optional:
– Nunca devolver null, ya que rompe con la filosofía de Optional
por completo.
– No usar Optional como tipo de datos de atributos. Optional
no implementa la interfaz Serializable. Esto se debe a que
no se concibió para ser atributo de clase, ni parámetro, sino
únicamente como tipo de retorno de un método par el caso de
devolver valores vacíos.

13

También podría gustarte