Skip to content

Commit a9b7ce8

Browse files
committed
feat(built-in-interfaces): Regras de Optional
Acrescentado as regras e os exemplos da classe Optional. Issue #21
1 parent f2eb1ff commit a9b7ce8

8 files changed

+276
-11
lines changed

book/04-lambda/sections/03-built-in-interfaces.asc

Lines changed: 106 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -270,25 +270,120 @@ include::{section-java-package}/builtininterfaces/BuiltInInterfaces_OperatorPrim
270270

271271
==== Optional
272272

273-
O Java 8 possui um tipo específico para representar valores que podem não ter sido informado, que é a classe `Optional`. A partir do Java 8, ela geralmente é uma opção melhor a retornar `null` em seus métodos.
273+
O Java 8 possui um tipo específico para representar valores que podem não ter sido informados, que é a classe `Optional`. A partir do Java 8, ela geralmente é uma opção melhor do que retornar ou armazenar `null`, pois seus métodos auxiliam em várias situações.
274274

275-
. Constructor
276-
277-
. ofNullable
275+
. É possível criar uma instância de `Optional` com valor através do método `of`.
276+
. É possível criar uma instância de `Optional` sem valor através do método `empty`.
277+
. É possível checar se uma instância de `Optional` possui um valor através do método `isPresent`.
278+
. É possível recuperar o valor de uma instância de `Optional` através do método `get`.
279+
+
280+
[source,java,indent=0]
281+
.{java-package}/builtininterfaces/BuiltInInterfaces_OptionalCreation.java
282+
----
283+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_OptionalCreation.java[tag=code]
284+
----
278285

279-
. get
286+
. Não é possível chamar o método `of` passando `null` como argumento. Para isso existe o método `ofNullable`.
287+
+
288+
[source,java,indent=0]
289+
.{java-package}/builtininterfaces/BuiltInInterfaces_OptionalNullable.java
290+
----
291+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_OptionalNullable.java[tag=code]
292+
----
293+
+
294+
.Saída no console
295+
[source,console]
296+
----
297+
java.lang.NullPointerException
298+
at java.util.Objects.requireNonNull(Objects.java:203)
299+
at java.util.Optional.<init>(Optional.java:96)
300+
at java.util.Optional.of(Optional.java:108)
301+
at org.j6toj8.lambda.builtininterfaces.BuiltInInterfaces_OptionalNullable.main(BuiltInInterfaces_OptionalNullable.java:11)
302+
false
303+
----
280304

281-
. isPresent
305+
. Com o método `ifPresent` é possível executar uma expressão lambda apenas se o `Optional` tiver valor.
306+
+
307+
[source,java,indent=0]
308+
.{java-package}/builtininterfaces/BuiltInInterfaces_OptionalIfPresent.java
309+
----
310+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_OptionalIfPresent.java[tag=code]
311+
----
312+
+
313+
.Saída no console
314+
[source,console]
315+
----
316+
Com Valor: valor
317+
----
282318

283-
. isEmpty
319+
. É possível recuperar um valor padrão caso o `Optional` esteja vazio. O método `orElse` retorna um valor diretamente, e o `orElseGet` retorna através de uma expressão lambda.
320+
+
321+
[source,java,indent=0]
322+
.{java-package}/builtininterfaces/BuiltInInterfaces_OptionalOrElse.java
323+
----
324+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_OptionalOrElse.java[tag=code]
325+
----
326+
+
327+
.Saída no console
328+
[source,console]
329+
----
330+
valor padrao
331+
valor padrao
332+
valor
333+
valor
334+
----
335+
+
336+
TIP: Observe que esse é um ótimo caso para lembrar de um benefício das expressões lambda. Na utilização de `orElseGet` a expressão lambda só é executada caso o `Optional` esteja vazio. No caso do exemplo, como é apenas o retorno de uma `String`, não faz diferença. Porém, se fosse uma operação mais pesada, você só iria de fato executá-la se o `Optional` estivesse vazio. Caso houvesse valor, a expressão lambda nem seria executada, evitando o custo de processamento.
284337

285-
. ifPresent
338+
. Também é possível lançar uma exceção caso um valor não esteja presente no `Optional` utilizando o método `orElseThrow`.
339+
+
340+
[source,java,indent=0]
341+
.{java-package}/builtininterfaces/BuiltInInterfaces_OptionalOrElseThrow.java
342+
----
343+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_OptionalOrElseThrow.java[tag=code]
344+
----
345+
+
346+
.Saída no console
347+
[source,console]
348+
----
349+
valor
350+
Exception in thread "main" java.lang.RuntimeException
351+
at org.j6toj8.lambda.builtininterfaces.BuiltInInterfaces_OptionalOrElseThrow.lambda$1(BuiltInInterfaces_OptionalOrElseThrow.java:17)
352+
at java.util.Optional.orElseThrow(Optional.java:290)
353+
at org.j6toj8.lambda.builtininterfaces.BuiltInInterfaces_OptionalOrElseThrow.main(BuiltInInterfaces_OptionalOrElseThrow.java:17)
354+
----
286355

287-
. orElse
356+
. Será lançada uma exceção ao chamar o método `get` em um `Optional` vazio.
357+
+
358+
[source,java,indent=0]
359+
.{java-package}/builtininterfaces/BuiltInInterfaces_OptionalGetEmpty.java
360+
----
361+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_OptionalGetEmpty.java[tag=code]
362+
----
363+
+
364+
.Saída no console
365+
[source,console]
366+
----
367+
valor
368+
Exception in thread "main" java.util.NoSuchElementException: No value present
369+
at java.util.Optional.get(Optional.java:135)
370+
at org.j6toj8.lambda.builtininterfaces.BuiltInInterfaces_OptionalGetEmpty.main(BuiltInInterfaces_OptionalGetEmpty.java:13)
371+
----
288372

289-
. orElseGet
290373

291-
. orElseThrow
374+
. Existem algumas classes para lidar com valor opcionais de variáveis primitivas, já que elas não podem ser utilizada com `generics`: `OptionalInt`, `OptionalDouble`, `OptionalLong`.
375+
+
376+
[source,java,indent=0]
377+
.{java-package}/builtininterfaces/BuiltInInterfaces_OptionalPrimitive.java
378+
----
379+
include::{section-java-package}/builtininterfaces/BuiltInInterfaces_OptionalPrimitive.java[tag=code]
380+
----
381+
+
382+
.Saída no console
383+
[source,console]
384+
----
385+
5
386+
----
292387

293388
.Referências
294389
****
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.util.Optional;
4+
5+
public class BuiltInInterfaces_OptionalCreation {
6+
7+
// tag::code[]
8+
// Exemplo de método sem Optional
9+
private static String recupereNomeMes(int mes) {
10+
if (mes == 1) {
11+
return "Janeiro";
12+
} else {
13+
return null;
14+
}
15+
}
16+
17+
// Exemplo de método retornando Optional
18+
private static Optional<String> recupereNomeMesOptional(int mes) {
19+
if (mes == 1) {
20+
return Optional.of("Janeiro"); // cria Optional com valor
21+
} else {
22+
return Optional.empty(); // cria Optional vazio
23+
}
24+
}
25+
26+
public static void main(String[] args) {
27+
String nomeMes1 = recupereNomeMes(1);
28+
if (nomeMes1 != null) { // valida se o valor existe através da tradicional comparação '!= null'
29+
System.out.println(nomeMes1);
30+
}
31+
32+
Optional<String> nomeMes2 = recupereNomeMesOptional(1);
33+
if (nomeMes2.isPresent()) { // valida se o Optional possui um valor preenchido
34+
System.out.println(nomeMes2.get()); // recupera o valor dentro do Optional
35+
}
36+
}
37+
// end::code[]
38+
39+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.util.Optional;
4+
5+
public class BuiltInInterfaces_OptionalGetEmpty {
6+
7+
public static void main(String[] args) {
8+
// tag::code[]
9+
Optional<String> optionalComValor = Optional.of("valor");
10+
System.out.println(optionalComValor.get()); // recupera o valor corretamente
11+
12+
Optional<String> optionalVazio = Optional.empty();
13+
System.out.println(optionalVazio.get()); // lança exceção
14+
// end::code[]
15+
}
16+
17+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.util.Optional;
4+
5+
public class BuiltInInterfaces_OptionalIfPresent {
6+
7+
// tag::code[]
8+
public static void main(String[] args) {
9+
Optional<String> optionalVazio = Optional.empty();
10+
Optional<String> optionalComValor = Optional.of("valor");
11+
12+
// A linha abaixo não irá imprimir nada, pois o optional está vazio
13+
optionalVazio.ifPresent(valor -> System.out.println("Vazio: " + valor));
14+
// A linha abaixo irá imprimir, pois o optional possui valor
15+
optionalComValor.ifPresent(valor -> System.out.println("Com Valor: " + valor ));
16+
}
17+
// end::code[]
18+
19+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.util.Optional;
4+
5+
public class BuiltInInterfaces_OptionalNullable {
6+
7+
// tag::code[]
8+
public static void main(String[] args) {
9+
// Exemplo tentando utilizar .of e passando 'null' como argumento
10+
try {
11+
Optional.of(null); // Lança NullPointerException nesta linha
12+
} catch (Exception e) {
13+
e.printStackTrace();
14+
}
15+
16+
// Exemplo utilizando o método correto: .ofNullable
17+
Optional<String> ofNullable = Optional.ofNullable(null); // Cria um Optional vazio
18+
System.out.println(ofNullable.isPresent()); // Imprime 'false' pois não possui valor
19+
}
20+
// end::code[]
21+
22+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.util.Optional;
4+
5+
public class BuiltInInterfaces_OptionalOrElse {
6+
7+
// tag::code[]
8+
public static void main(String[] args) {
9+
// Exemplo com Optional vazio
10+
Optional<String> optionalVazio = Optional.empty();
11+
12+
// as duas variáveis abaixo terão a String "valor padrao", pois o optional está vazio
13+
String orElse = optionalVazio.orElse("valor padrao"); // obtém a String diretamente
14+
String orElseGet = optionalVazio.orElseGet(() -> { return "valor padrao"; }); // obtém a String através da expressão lambda
15+
16+
System.out.println(orElse);
17+
System.out.println(orElseGet);
18+
19+
// Exemplo com Optional com valor
20+
Optional<String> optionalComValor = Optional.of("valor");
21+
22+
// as duas variáveis abaixo irão utilizar o valor presente no optional, pois ele já está preenchido
23+
String orElse2 = optionalComValor.orElse("valor padrao");
24+
String orElseGet2 = optionalComValor.orElseGet(() -> { return "valor padrao"; });
25+
26+
System.out.println(orElse2);
27+
System.out.println(orElseGet2);
28+
}
29+
// end::code[]
30+
31+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.util.Optional;
4+
5+
public class BuiltInInterfaces_OptionalOrElseThrow {
6+
7+
// tag::code[]
8+
public static void main(String[] args) {
9+
Optional<String> optionalVazio = Optional.empty();
10+
Optional<String> optionalComValor = Optional.of("valor");
11+
12+
// Nesse caso será impresso o valor presente em Optional, pois ele está preenchido
13+
String orElseThrow1 = optionalComValor.orElseThrow(() -> new RuntimeException());
14+
System.out.println(orElseThrow1);
15+
16+
// Nesse caso será lançada exceção, pois o Optional não está preenchido
17+
String orElseThrow2 = optionalVazio.orElseThrow(() -> new RuntimeException());
18+
}
19+
// end::code[]
20+
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.j6toj8.lambda.builtininterfaces;
2+
3+
import java.util.OptionalInt;
4+
5+
public class BuiltInInterfaces_OptionalPrimitive {
6+
7+
public static void main(String[] args) {
8+
// tag::code[]
9+
OptionalInt optionalComValor = OptionalInt.of(5);
10+
OptionalInt optionalVazio = OptionalInt.empty();
11+
12+
if (optionalComValor.isPresent()) {
13+
System.out.println(optionalComValor.getAsInt());
14+
}
15+
if (optionalVazio.isPresent()) {
16+
System.out.println(optionalVazio.getAsInt());
17+
}
18+
// end::code[]
19+
}
20+
21+
}

0 commit comments

Comments
 (0)