Abordagens pré-Java 8:
- Lançar exceção: reservado para situações excepcionais e dispendioso devido à captura de rastreamento de pilha.
- Retornar null: exige código especial para lidar com a possibilidade de retorno null, podendo causar erros como NullPointerException.
A abordagem do Java 8:
- Introdução da classe Optional, um contêiner imutável que pode conter um valor ou estar vazio.
- Evita o uso de null e simplifica o tratamento de valores ausentes sem lançar exceções.
- Métodos podem retornar Optional para representar a ausência de um valor.
Vantagens do uso de Optional:
- Evita exceções e problemas com null.
- Permite que o cliente decida o que fazer quando o valor está ausente (fornecer valor padrão, lançar exceção, etc.).
- Facilita o código sem a necessidade de tratamento explícito de null.
Métodos úteis da classe Optional:
- Optional.of(value): cria um Optional com um valor não nulo.
- Optional.ofNullable(value): cria um Optional, mas aceita valores nulos.
- orElse(value): retorna um valor padrão se o Optional estiver vazio.
- orElseThrow(): lança exceção se o valor não estiver presente.
- map(), flatMap(), filter(): permitem manipulação de valores dentro do Optional.
Evite envolver coleções em Optional:
- Para tipos de contêiner como listas ou arrays, retorne coleções vazias em vez de Optional>.
Considerações de desempenho:
- O uso de Optional tem custo em termos de alocação de objetos.
- Para tipos primitivos, use OptionalInt, OptionalLong e OptionalDouble para evitar o custo do empacotamento.
Cuidado com outros usos de Optional:
Evite usá-los como chaves ou valores de Map ou em coleções.
Evite usá-los como campos de instância, a menos que faça sentido, como em getters opcionais.
Exemplos de Código
Exemplo 1: Uso básico de Optional
import java.util.Optional;
public class ExemploOptional {
public static Optional<String> encontrarNome(String[] nomes, String nomeBuscado) {
for (String nome : nomes) {
if (nome.equalsIgnoreCase(nomeBuscado)) {
return Optional.of(nome);
}
}
return Optional.empty(); // Retorna Optional vazio se não encontrar o nome
}
public static void main(String[] args) {
String[] nomes = {"João", "Maria", "Ana"};
Optional<String> nomeEncontrado = encontrarNome(nomes, "Maria");
nomeEncontrado.ifPresent(nome -> System.out.println("Nome encontrado: " + nome));
System.out.println(nomeEncontrado.orElse("Nome não encontrado"));
}
}
Exemplo 2: Uso de orElseThrow
import java.util.Optional;
public class ExemploOrElseThrow {
public static Optional<Integer> buscarIdade(String nome) {
if (nome.equals("João")) {
return Optional.of(30);
}
return Optional.empty(); // Retorna Optional vazio se o nome não for "João"
}
public static void main(String[] args) {
Optional<Integer> idade = buscarIdade("Maria");
// Lança uma exceção se o valor não estiver presente
int valorIdade = idade.orElseThrow(() -> new IllegalArgumentException("Idade não encontrada!"));
System.out.println("Idade: " + valorIdade);
}
}
Exemplo 3: Optional com tipos primitivos
import java.util.OptionalInt;
public class ExemploOptionalInt {
public static OptionalInt buscarIdade(String nome) {
if (nome.equals("João")) {
return OptionalInt.of(30);
}
return OptionalInt.empty(); // Retorna OptionalInt vazio se o nome não for "João"
}
public static void main(String[] args) {
OptionalInt idade = buscarIdade("João");
if (idade.isPresent()) {
System.out.println("Idade encontrada: " + idade.getAsInt());
} else {
System.out.println("Idade não encontrada");
}
}
}
Top comments (0)