✅ Tópico: Develop code that uses the Optional class

O objetivo aqui é saber quando e como usar a classe Optional<T>, introduzida no Java 8 para evitar NullPointerException de forma mais elegante e segura.


☑️ O que é Optional<T>?

Optional é um container que pode ou não conter um valor não-nulo. Ele te obriga a lidar explicitamente com a ausência de valor, evitando acessos inseguros a referências nulas.


🔧 Criação de Optional

Optional<String> opt1 = Optional.of("valor");         
// Não pode ser null

Optional<String> opt2 = Optional.ofNullable("valor");

// Pode ser null

Optional<String> opt3 = Optional.empty();

// Representa ausência de valor

📌 Principais métodos

MétodoO que faz
isPresent()Retorna true se há valor
ifPresent(Consumer)Executa algo se houver valor
get()Retorna o valor (⚠️ lança exceção se vazio)
orElse(valor)Retorna o valor, ou outro se vazio
orElseGet(Supplier)Retorna o valor, ou resultado de uma função
orElseThrow()Lança exceção se vazio
map(Function)Transforma o valor, se presente
flatMap(Function)Igual ao map, mas evita Optional<Optional<T>>
filter(Predicate)Retorna o mesmo Optional se o valor passar no filtro

📘 Exemplos

Optional<String> nome = Optional.of("Carlos");

// get()
System.out.println(nome.get());

// Carlos

// ifPresent
nome.ifPresent(n -> System.out.println(n.toUpperCase()));

// CARLOS

// orElse
System.out.println(nome.orElse("Desconhecido"));

// Carlos

// orElse com vazio
Optional<String> vazio = Optional.empty();
System.out.println(vazio.orElse("Nada aqui"));

// Nada aqui

// map
Optional<Integer> tamanho = nome.map(String::length);
System.out.println(tamanho.get());

// 6

😈 Pegadinhas e cuidados na prova:

  1. Nunca use .get() sem checar .isPresent() antes!
  2. Optional.of(null) → lança NullPointerException
  3. orElse() executa sempre o argumento (cuidado com código pesado)
  4. Prefira orElseGet() para lógica preguiçosa (lazy)
  5. flatMap() é usado quando a função retorna um Optional<T>

🧠 Exemplo com filter:

Optional<String> nome = Optional.of("Ana");
nome = nome.filter(n -> n.startsWith("A"));
System.out.println(nome.isPresent());

// true

nome = nome.filter(n -> n.length() > 10);
System.out.println(nome.isPresent());

// false

📌 Exemplo flatMap

Optional<String> nome = Optional.of("Java");
Optional<Optional<Integer>> comprimento =

nome.map(n -> Optional.of(n.length()));
System.out.println(comprimento);

// Optional[Optional[4]]

Optional<Integer> correto =

nome.flatMap(n -> Optional.of(n.length()));
System.out.println(correto);

// Optional[4]

Questão 1

Qual das seguintes chamadas lança uma exceção?

A) Optional.of("java")
B) Optional.empty()
C) Optional.ofNullable(null)
D) Optional.of(null)


Questão 2

Dado:

Optional<String> nome = Optional.of("Carlos");
System.out.println(nome.orElse("Desconhecido"));

O que é impresso?

A) Desconhecido
B) Carlos
C) Optional[Carlos]
D) null


Questão 3

Qual a saída do código?

Optional<String> nome = Optional.of("Java");
System.out.println(nome.map(String::length).get());

A) 4
B) Optional[4]
C) Java
D) Erro de compilação


Questão 4

Dado:

Optional<String> nome = Optional.empty();
System.out.println(nome.orElseGet(() -> "Fallback"));

O que será impresso?

A) Fallback
B) null
C) Optional[Fallback]
D) Exceção


Questão 5

Qual afirmação é verdadeira?

A) Optional.get() é seguro em qualquer situação
B) Optional.ofNullable(null) lança exceção
C) Optional.of(null) é seguro
D) Optional.orElseGet() é preferido para valores computados


Questão 6

Qual das seguintes opções transforma corretamente um Optional<String> em Optional<Integer> representando seu tamanho?

A) opt.flatMap(s -> s.length())
B) opt.map(s -> s.length())
C) opt.map(s -> Optional.of(s.length()))
D) opt.map(s -> s.toString())


Questão 7

Considere:

Optional<String> nome = Optional.of("Ana");
System.out.println(nome.filter(n -> n.startsWith("B")).isPresent());

A) true
B) false
C) Ana
D) Exception


Questão 8

O que retorna este código?

Optional<String> opt = Optional.empty();
opt.get();

A) null
B) "Optional"
C) Optional.empty
D) NoSuchElementException


Questão 9

Assinale a alternativa que melhor representa a utilidade de flatMap em Optional.

A) Evita exceções ao chamar get()
B) Retorna Optional<Optional<T>>
C) Aplica uma função que retorna um Optional<T> e achata o resultado
D) Converte qualquer Optional em Optional<String>


Questão 10

Qual das chamadas abaixo sempre executa seu argumento, mesmo que o Optional tenha valor?

A) orElse("valor")
B) orElseGet(() -> "valor")
C) map(String::length)
D) filter(s -> s != null)



📘 Gabarito Comentado

  1. DOptional.of(null) lança NullPointerException.
  2. B – O valor é "Carlos" e orElse não é usado.
  3. Amap transforma em Optional<Integer> e get() retorna 4.
  4. A – O valor está ausente, então orElseGet é chamado, retornando "Fallback".
  5. DorElseGet() é preferido para evitar execução desnecessária.
  6. Bmap aplica a função s -> s.length() corretamente.
  7. B"Ana" não começa com "B", logo o Optional fica vazio.
  8. Dget() em Optional.empty() lança NoSuchElementException.
  9. CflatMap é usado para “achatar” resultados de funções que já retornam Optional.
  10. AorElse("valor") sempre avalia o argumento, mesmo se não for usado.

Deixe um comentário