Neste guia você irá aprender como funciona o Optional
, um novo recurso adicionado no Java 8 e saberá como usá-lo.
Introdução
A classe Optional
foi adicionada na versão do 8 no pacote java.util
. Esta classe foi introduzida para verificar se um valor está presente, evitando o famoso erro de NullPointerException
.
Um objeto Optional
é um container que pode ou não conter um valor.
Métodos mais usados
A classe Optional
possui vários métodos, entre eles temos o isPresent()
e get()
.
-
isPresent()
: Verifica se o objetoOptional
possui algum valor que seja diferente de vazio ounull
. Retornatrue
se tiver algum valor, caso contrário retornafalse
. -
get()
: Recupera o valor de um objetoOptional
.
Semelhante ao
isPresent()
o métodoisEmpty()
retornatrue
se estiver vazio, caso contrário, retornarátrue
. Este método foi adicionado no Java 11.
package to.dev;
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
Optional<String> stringOptional = Optional.of("Hello");
if (stringOptional.isPresent()) {
System.out.println(stringOptional.get()); // Hello
}
}
}
Para criar um Optional
é preciso usar o método Optional.of(T value)
, este método retorna um Optional<T>
do mesmo tipo do argumento fornecido em of(T value)
.
Ex. Optional<Long> longOptional = Optional.of(1L);
Optional.of(T value)
e Optional.ofNullable(T value)
Só use of(T value)
quando o argumento fornecido NUNCA será null
. Caso contrário, será lançado um NullPointerException
. Para evitar esse erro use ofNullable(T value)
public class OptionalExample {
public static void main(String[] args) {
Optional<String> stringOptional = Optional.ofNullable(null);
if (stringOptional.isPresent()) {
System.out.println(stringOptional.get());
}
}
}
Criando um Optional
vazio
Para criar um Optional
vazio use Optional.empty()
. Ex. Optional<String> stringOptional = Optional.empty();
Optional
com valores default - orElse(T other)
Caso um Optional
esteja vazio e você queira retorna um valor padão basta usar o método orElse(T other)
.
package to.dev;
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
Optional<Long> longOptional = Optional.ofNullable(null);
System.out.println(longOptional.orElse(99L)); // 99
}
}
Optional
com valores default - orElseGet(Supplier<? extends T> supplier)
Esta alternativa recebe um Supplier
como argumento, permitindo que você execute alguma operação.
Supplier
: É uma interface funcional que não recebe argumentos, mas sempre retorna um valor.
package to.dev;
import java.time.LocalDate;
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
Optional<Long> longOptional = Optional.ofNullable(null);
System.out.println(longOptional.orElseGet(() -> { // 29
int i = LocalDate.now().getDayOfMonth();
return (long) i;
}));
}
}
orElse(T other)
vs orElseGet(Supplier<? extends T> supplier)
orElse(T other)
retorna o valor dentro do container Optional
se estiver presente, caso contrário, irá retornar o valor fornecido no argumento do método. orElseGet(Supplier<? extends T> supplier)
: retorna o valor dentro do container Optional
, caso contrário, irá invocar o Supplier
e retornará o resultado da invocação.
Filtrando um Optional
Para filtrar algum valor de Optional
use o método filter(Predicate<? super T> predicate)
.
Predicate
: É uma interface funcional que recebe um valor e sempre retorna um valor booleano.
package to.dev;
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
Optional<Long> longOptional = Optional.ofNullable(30L);
Optional<Long> longFilter = longOptional.filter(v -> v > 18); // true
if (longOptional.isPresent()) {
System.out.println(longFilter.get()); // 30
}
}
}
Modificando o valor de um Optional
com map(Function<? super T, ? extends U> mapper)
O método map()
serve para modificar um valor dentro de um container Optional
. Para isso é passado uma Function
com argumento.
Function
: É uma interface funcional que recebe um valor como argumento e retorna um valor que pode igual ou diferente do argumento passado.
package to.dev;
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
Optional<String> longOptional = Optional.ofNullable("Hello");
Optional<String> longMap = longOptional.map(v -> {
if (v.contains("Hello")) {
return "Hello World";
} else {
return "Hello";
}
});
System.out.println(longMap.get()); // Hello World
}
}
Recebendo um Optional
de outro Optional
com flatMap(Function<? super T, ? extends Optional<? extends U>> mapper)
O flatMap(Function<? super T, ? extends Optional<? extends U>> mapper)
é usado quando você recebe um objeto Optional
de um container Optional
, Optional<Optional<Long>> longOptional = Optional.of(Optional.empty());
.
package to.dev;
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
Optional<String> stringOptional = Optional.of("Hello World");
Optional<Optional<String>> optionalStringOptional = Optional.of(stringOptional);
System.out.println(optionalStringOptional);
Optional<String> output = optionalStringOptional.flatMap(value -> value.map(String::toLowerCase));
System.out.println(output);
}
}
Executando uma lógica se o Optional
estiver presente
Caso queira executar alguma operação se um valor estiver presente, uma alternativa é usar o método ifPresent(Consumer<? super T> consumer)
.
Consumer
: É uma interface funcional que recebe argumentos, mas não retorna nenhum valor.
package to.dev;
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
Optional<String> longOptional = Optional.ofNullable("Hello");
Optional<String> longMap = longOptional.map(v -> {
if (v.contains("Hello")) {
return "Hello World";
} else {
return "Hello";
}
});
longMap.ifPresent(v -> System.out.println(v)); // Hello World
}
}
Tratando exceções com orElseThrow(Supplier<? extends X> exceptionSupplier)
O método orElseThrow(Supplier<? extends X> exceptionSupplier)
retorna o valor caso ele esteja presente, caso contrário, ele irá lançar um exceção fornecida pelo desenvolvedor.
Este método só está disponível no Java 10.
package to.dev;
import java.util.Optional;
class EmptyException extends Exception {
public EmptyException() {
super("Not found value");
}
}
public class OptionalExample {
public static void main(String[] args) throws EmptyException {
Optional<String> stringOptional = Optional.ofNullable(null);
System.out.println(stringOptional.orElseThrow()); // throws -> NoSuchElementException: No value present
System.out.println(stringOptional.orElseThrow(EmptyException::new)); // throws -> EmptyException: Not found value
}
}
Referência: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Optional.html
Top comments (0)