Antes de tudo, verifique a declaração de ambos os métodos.
1) OrElse: Execute a lógica e passe o resultado como argumento.
public T orElse(T other) {
return value != null ? value : other;
}
2) OrElseGet: executar lógica se o valor dentro do opcional for nulo
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
Algumas explicações sobre a declaração acima:
O argumento “Optional.orElse” sempre é executado independentemente do valor do objeto em opcional (nulo, vazio ou com valor). Sempre considere o ponto acima mencionado ao usar “Optional.orElse”, caso contrário, o uso de “Optional.orElse” pode ser muito arriscado na seguinte situação.
Risco-1) Problema no log: se o conteúdo dentro do orElse contiver alguma instrução de log: Nesse caso, você terminará o log todas as vezes.
Optional.of(getModel())
.map(x -> {
//some logic
})
.orElse(getDefaultAndLogError());
getDefaultAndLogError() {
log.error("No Data found, Returning default");
return defaultValue;
}
Risco-2) Problema de desempenho: se o conteúdo no orElse é demorado: o conteúdo intensivo pode ser qualquer chamada de banco de dados de operações de E / S, chamada de API, leitura de arquivo. Se colocarmos esse conteúdo em orElse (), o sistema acabará executando um código inútil.
Optional.of(getModel())
.map(x -> //some logic)
.orElse(getDefaultFromDb());
getDefaultFromDb() {
return dataBaseServe.getDefaultValue(); //api call, db call.
}
Risco-3) Estado ilegal ou problema de bug: se o conteúdo dentro do orElse está modificando algum estado do objeto: Podemos estar usando o mesmo objeto em outro local, digamos na função Optional.map e isso pode nos colocar em um bug crítico.
List<Model> list = new ArrayList<>();
Optional.of(getModel())
.map(x -> {
})
.orElse(get(list));
get(List < String > list) {
log.error("No Data found, Returning default");
list.add(defaultValue);
return defaultValue;
}
Então, quando podemos ir com orElse ()?
Prefira usar orElse quando o valor padrão for algum objeto constante, enum. Em todos os casos acima, podemos usar Optional.orElseGet () (que é executado apenas quando Optional contém valor não vazio) em vez de Optional.orElse (). Por quê?? Em orElse, passamos o valor padrão do resultado, mas em orElseGet passamos como Supplier e o método de Supplier somente é executado se o valor em Opcional for nulo.
Principais conclusões disso:
- Não use “Optional.orElse” se ele contiver alguma instrução de log.
- Não use “Optional.orElse” se ele contiver lógica demorada.
- Não use “Optional.orElse” se estiver modificando algum estado do objeto.
- Use “Optional.orElse” se precisarmos retornar uma constante, enumeração.
- Prefira “Optional.orElseGet” nas situações mencionadas nos pontos 1,2 e 3.
Eu expliquei isso no ponto 2 ( “Optional.map/Optional.orElse”! = “If / else” ) no meu blog médio. Use Java8 como programador e não como codificador
orElseGet
, chama o fornecedor apenas se o valor estiver ausente.