Seu principal erro é que você ainda está pensando em termos processuais. Isso não é uma crítica a você como pessoa, é apenas uma observação. Pensar em termos mais funcionais vem com o tempo e a prática e, portanto, os métodos são apresentados e parecem as coisas corretas mais óbvias para você. Seu erro secundário secundário é criar o seu Opcional dentro do seu método. O Opcional tem como objetivo ajudar a documentar que algo pode ou não retornar um valor. Você pode não conseguir nada.
Isso fez com que você escrevesse um código perfeitamente legível que parecesse perfeitamente razoável, mas você foi seduzido pelas vil sedutoras sedutoras que são get e isPresent.
É claro que a pergunta rapidamente se torna "por que o isPresent está chegando lá?"
Uma coisa que muitas pessoas aqui sentem falta é isPresent (), que não é algo que é feito para um novo código escrito por pessoas totalmente a bordo com o quão bom é o lambda útil e quem gosta da coisa funcional.
No entanto, oferece alguns (dois) benefícios bons, ótimos e charmosos (?):
- Facilita a transição do código legado para usar os novos recursos.
- Facilita as curvas de aprendizado do Opcional.
O primeiro é bastante simples.
Imagine que você tenha uma API parecida com esta:
public interface SnickersCounter {
/**
* Provides a proper count of how many snickers have been consumed in total.
*/
public SnickersCount howManySnickersHaveBeenEaten();
/**
* returns the last snickers eaten.<br>
* If no snickers have been eaten null is returned for contrived reasons.
*/
public Snickers lastConsumedSnickers();
}
E você tinha uma classe herdada usando isso como tal (preencha os espaços em branco):
Snickers lastSnickers = snickersCounter.lastConsumedSnickers();
if(null == lastSnickers) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers);
}
Um exemplo inventado para ter certeza. Mas tenha paciência comigo aqui.
O Java 8 já foi lançado e estamos nos esforçando para entrar a bordo. Portanto, uma das coisas que fazemos é que queremos substituir nossa interface antiga por algo que retorne Opcional. Por quê? Porque, como alguém já mencionou graciosamente:
Isso elimina a suposição de se algo pode ou não ser nulo.
Isso já foi apontado por outros. Mas agora temos um problema. Imagine que temos (desculpe-me enquanto pressiono alt + F7 em um método inocente), 46 lugares em que esse método é chamado em código legado bem testado que, caso contrário, faz um excelente trabalho. Agora você precisa atualizar tudo isso.
É aqui que está presente o brilho.
Porque agora: Snickers lastSnickers = snickersCounter.lastConsumedSnickers (); if (null == lastSnickers) {lança novo NoSuchSnickersException (); } else {consumer.giveDiabetes (lastSnickers); }
torna-se:
Optional<Snickers> lastSnickers = snickersCounter.lastConsumedSnickers();
if(!lastSnickers.isPresent()) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers.get());
}
E essa é uma mudança simples que você pode dar ao novo junior: ele pode fazer algo útil e poderá explorar a base de código ao mesmo tempo. ganha-ganha. Afinal, algo semelhante a esse padrão é bastante difundido. E agora você não precisa reescrever o código para usar lambdas ou qualquer coisa. (Nesse caso em particular, seria trivial, mas deixo pensando em exemplos em que isso seria difícil como exercício para o leitor.)
Observe que isso significa que a maneira como você fez isso é essencialmente uma maneira de lidar com o código herdado sem fazer reescritas caras. E o novo código?
Bem, no seu caso, onde você apenas deseja imprimir algo, basta:
snickersCounter.lastConsumedSnickers (). ifPresent (System.out :: println);
O que é bastante simples e perfeitamente claro. O ponto que está subindo lentamente à superfície é que existem casos de uso para get () e isPresent (). Eles estão lá para permitir que você modifique o código existente mecanicamente para usar os tipos mais recentes sem pensar muito nisso. O que você está fazendo é, portanto, equivocado das seguintes maneiras:
- Você está chamando um método que pode retornar nulo. A idéia correta seria que o método retorne nulo.
- Você está usando os métodos bandaid herdados para lidar com isso opcional, em vez de usar os novos métodos saborosos que contêm fantasia lambda.
Se você deseja usar o Opcional como uma verificação simples de segurança nula, o que você deveria ter feito é simplesmente o seguinte:
new Optional.ofNullable(employeeServive.getEmployee())
.map(Employee::getId)
.ifPresent(System.out::println);
Obviamente, a versão mais bonita disso se parece com:
employeeService.getEmployee()
.map(Employee::getId)
.ifPresent(System.out::println);
A propósito, enquanto isso não é de forma alguma necessário, recomendo o uso de uma nova linha por operação, para facilitar a leitura. Fácil de ler e entender supera a concisão em qualquer dia da semana.
É claro que este é um exemplo muito simples, onde é fácil entender tudo o que estamos tentando fazer. Nem sempre é tão simples na vida real. Mas observe como, neste exemplo, o que estamos expressando são nossas intenções. Queremos OBTER o funcionário, OBTER seu ID e, se possível, imprimi-lo. Esta é a segunda grande vitória do Opcional. Isso nos permite criar um código mais claro. Eu também acho que fazer coisas como criar um método que faça um monte de coisas para que você possa alimentá-lo em um mapa é geralmente uma boa idéia.