-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoptional.java
108 lines (87 loc) · 4.84 KB
/
optional.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import java.util.Optional;
class Main {
public static String metodo() {
System.out.println("dentro do método");
return "ola";
}
public static void main(String[] args) {
//Optional<String> e = Optional.of(null); //erro Optional.of() não pode receber algo nulo então pra usar ele deve ter certeza que o valor não será nulo, melhor usar caso usar ofNullable() que suporta nulo
Optional<String> e = Optional.ofNullable(null);
System.out.println(e.orElseGet(()->"1"));//saida 1, orElseGet permite criar uma função a ser executada
System.out.println(e.orElse("1"));//saida 1, pode passar uma função para o orElse tambem
Optional<String> opt = Optional.empty();
System.out.println(opt.orElse(metodo()));
System.out.println(opt.orElseGet(() -> metodo()));
//Como o Optional é vazio, ambos chamarão o método.
//String valor = opt.orElseThrow(IllegalArgumentException::new);//caso se vazio orElseThrow lança um erro
//Mas se o Optional não for vazio:
opt = Optional.of("teste");
System.out.println(opt.orElse(metodo()));
System.out.println(opt.orElseGet(() -> metodo()));
//O método só é chamado no primeiro caso, pois o retorno dele deve ser passado para orElse. com orElse o método é chamado mesmo se optional não for vazio
//Já o orElseGet só chama o método se o Optional for vazio (então neste caso, ele não é chamado). só é chamado quando realmente necessário.
Optional<String> e1 = Optional.ofNullable("er");
System.out.println(e1.orElse("345345345"));//aqui como não foi chamado um metodo vai retornar "er" e não o valor dentro do orElse
String t1 = e1.isPresent() ? e1.get() : null;
//outra forma de fazer o mesmo da linha acima:
t1 = e1.orElse(null); //retorno dentro do orElse deve ser do mesmo tipo
System.out.println(t1);
//ex: final Collection<T> teste = Optional.ofNullable(pessoa.getId()).map(p -> this.testeService.findById(p.getId())).orElseGet(() -> new ArrayList<>());
//se caso pessoa.getId Não for NULL será retornado o que está no map(), senão é retornado o orElseGet
/*
orElseGet vs. orElse
Ambos retornam algo se o Optional não tiver um valor.
A diferença é no orElse você fornece o valor a ser retornado, e no orElseGet você fornece um Supplier (um objeto que retorna o valor). Ex:
Optional<String> opt = Optional.empty();
System.out.println(opt.orElse("ola"));
System.out.println(opt.orElseGet(() -> "ola"));
Ambos imprimem "ola". Evidentemente que dentro do orElseGet você pode criar um método tão complexo quanto queira:
System.out.println(opt.orElseGet(() -> {
// faz outras coisas complexas aqui
return resultadoDasCoisasComplexasAcima;
}));
Mas nada impede que o método que faz várias coisas complexas sejam chamado diretamente e o resultado passado para orElse:
System.out.println(opt.orElse(metodoQueFazVariasCoisasComplexas()));
A diferença é que nesse caso o método é chamado e seu retorno é passado para orElse. Já se eu chamar orElseGet, o método só é chamado se o Optional não tiver um valor:
public String metodo() {
System.out.println("dentro do método");
return "ola";
}
...
Optional<String> opt = Optional.empty();
System.out.println(opt.orElse(metodo()));
System.out.println(opt.orElseGet(() -> metodo()));
Como o Optional é vazio, ambos chamarão pelo método. A saída é:
dentro do método
ola
dentro do método
ola
Mas se o Optional não for vazio:
Optional<String> opt = Optional.of("teste");
System.out.println(opt.orElse(metodo()));
System.out.println(opt.orElseGet(() -> metodo()));
O método só é chamado no primeiro caso, pois o retorno dele deve ser passado para orElse. Já o orElseGet só chama o método se o Optional for vazio (então neste caso, ele não é chamado).
A saída é:
dentro do método
teste
teste
Isso faz diferença nos casos em que o método a ser chamado é muito custoso (faz operações complexas, demoradas, gasta muito processamento ou memória, o objeto retornado é "muito grande", etc).
Nesses casos, usar orElseGet é uma opção melhor que orElse, pois aí o método só é chamado quando realmente necessário.
---------------------------------------
em vez de usar vários get junto podendo dar NPE, usa-se optional que previne NPE:
product.getLatestVersion().getProductData().getTradeItem().getInformationProviderOfTradeItem().getGln();
usando Optional:
Optional.ofNullable(product).map(
Product::getLatestVersion
).map(
ProductVersion::getProductData
).map(
ProductData::getTradeItem
).map(
TradeItemType::getInformationProviderOfTradeItem
).map(
PartyInRoleType::getGln
).orElse(null);
*/
}
}