Clase Optional
La Clase Optional aparece a partir de Java 9, y simplemente hace referencia a un objeto o un valor null. Es decir hay situaciones en que ciertas sentencias nos podrá devolver algo o no. Siempre los “null” nos puede generar problemas, si usamos esta clase no. Ya que contempla la referencia a nada, intenta substituir a comprobaciones de tipo: “if (nota!=null) {}”
Resumen de cuatro métodos principales:
- boolean isPresent(): devuelve si tiene valor o no.
- get(): devuelve el objeto.
- Optional.of(objeto): constructor de Optional estático (no acepta null).
- Optional.ofNullable(objeto): mejor opción que la anterior ya que si acepta nulls.
- boolean Optional.empty(): devuelve false si no existe el objeto.
Ejemplo:
public class Nota {
private String asignatura;
private double valor;
public String getAsignatura() {
return asignatura;
}
public void setAsignatura(String asignatura) {
this.asignatura = asignatura;
}
public double getValor() {
return valor;
}
public void setValor(double valor) {
this.valor = valor;
}
public Nota(String asignatura, double valor) {
super();
this.asignatura = asignatura;
this.valor = valor;
}
}
public class Principal {
public static void main(String[] args) {
List<Nota> notas= new ArrayList<Nota>();
notas.add(new Nota("matematicas",3));
notas.add(new Nota("lengua",10));
notas.add(new Nota("ingles",5));
notas.add(new Nota("fisica",7));
Nota nota= buscarNotaSobresaliente(notas);
// Estas sentencias nos pueden generar el típico java.lang.NullPointerExcepcion
System.out.println(nota.getValor());
System.out.println(nota.getAsignatura());
}
public static Nota buscarNotaSobresaliente(List<Nota> notas) {
Nota nota=null;
for (Nota unaNota:notas) {
if (unaNota.getValor()>=9) {
nota= unaNota;
}
}
return nota;
}
}
Esto se soluciona con un !=null
if (nota!=null) {
System.out.println(nota.getValor());
System.out.println(nota.getAsignatura());
}
O usando la clase Optional:
Optional<Nota> oNota= buscarNotaSobresaliente(notas);
if (oNota.isPresent()) {
Nota nota=oNota.get();
System.out.println(nota.getValor());
System.out.println(nota.getAsignatura());
}
}
public static Optional<Nota> buscarNotaSobresaliente(List<Nota> notas) {
for (Nota unaNota:notas) {
if (unaNota.getValor()>=9) {
return Optional.of(unaNota);
}
}
return Optional.empty();
}
Ejemplo con Optional.of():
public Optional<Capitulo> buscarCapitulo (String nombre) {
for (Capitulo c: capitulos) {
if (c.getNombre().equals("nombre")) {
return Optional.of(c);
}
}
return Optional.empty();
}
//main...
Optional<Capitulo> busqueda;
busqueda = l.buscarCapitulo("capitulo2");
busqueda.ifPresent((x)->System.out.println(x.getLongitud())); // lambda con ifPresent()
Recordemos que un Optional es un tipo que permite almacenar dos valores (valor concreto/valor nulo).
Entonces los Optionals nos permiten manejar valores que podrían no existir. Esto nos ayuda a reducir la cantidad de excepciones generadas por valores nulos (NullPointerExceptions). La clase Optional cuenta con varios métodos útiles que nos van a permitir manejar tanto la creación, la obtención y la verificación de los valores. Esta clase se ha ido ampliando con todas las posibilidades lógicas/booleanas posibles. más posibilidades
Ejemplo de un método que se utiliza con lambda
Un método muy cómodo de usar de Optional es ifPresentOrElse(), y cómo os imáginais es un if else dependiendo si tiene objeto el optional o no. Sintáxis con el uso de lambda:
public void ifPresentOrElse(Consumer<T> action,
Runnable emptyAction)
Ejemplo:
Optional<Integer> op = Optional.ofNullable(9455); // creamos el Optional
op.ifPresentOrElse(
(value) -> { System.out.println(
"Value is present, its: "
+ value); },
() -> { System.out.println(
"Value is empty"); });
Ejercicio 1
Crear un programa que simula un sistema de registro de usuarios (sin persistencia guardar en colecciones). El programa tendrá las siguientes funcionalidades:
- Registrar un nuevo usuario con nombre, apellido y correo electrónico.
- Buscar un usuario por su nombre y apellido.
- Actualizar el correo electrónico de un usuario existente.
- Eliminar un usuario existente. Para gestionar la ausencia de valores, utilizaremos la clase Optional.