Bem-vindo ao blog de Felix Ricardo Gilioli

Compartilhando conhecimento sobre tecnologia, programação e engenharia de software

Diferença entre os métodos orElse e orElseGet da classe Optional em Java

| Categorias: Java

O Java 8 introduziu a classe Optional como uma maneira de lidar com valores nulos de forma mais segura e expressiva. Ela é uma das grandes melhorias da linguagem para evitar exceções NullPointerException ao trabalhar com valores que podem ou não estar presentes. Entre os métodos disponíveis na classe Optional, dois deles são frequentemente usados para recuperar valores padrão quando o valor dentro do Optional não está presente: orElse e orElseGet. Embora ambos tenham propósitos semelhantes, eles diferem no momento em que o valor padrão é fornecido e no tratamento de computação tardia (lazy evaluation).

O que é a classe Optional?

Antes de mergulharmos nas diferenças entre orElse e orElseGet, é importante entender o que é a classe Optional. O Optional é uma classe que representa um container que pode ou não conter um valor não nulo. Ele foi projetado para encorajar a prática da programação defensiva, forçando o desenvolvedor a explicitamente tratar o cenário em que um valor pode estar ausente.

O método orElse

O método orElse é uma das maneiras mais simples de obter um valor de um Optional. Ele tem a seguinte assinatura:


T orElse(T other)

Se o valor dentro do Optional estiver presente, o método retornará esse valor. Caso contrário, ele retornará o valor passado como argumento (other). O argumento other pode ser qualquer valor do tipo apropriado para o Optional, mas é importante notar que, independentemente de o valor dentro do Optional estar presente ou não, o argumento other será avaliado sempre que o método orElse for chamado.

Exemplo de uso do orElse:


Optional<String> optionalValue = Optional.ofNullable(someValue);
String result = optionalValue.orElse("Valor Padrão");

O método orElseGet

O método orElseGet também é usado para obter um valor de um Optional, mas com uma diferença fundamental em relação ao orElse. Sua assinatura é a seguinte:


T orElseGet(Supplier<? extends T> supplier)

Em vez de receber diretamente o valor padrão, o orElseGet recebe um Supplier, que é uma interface funcional que representa um fornecedor de valores. A diferença crucial aqui é que o Supplier só será invocado e o valor retornado por ele será criado se o valor dentro do Optional não estiver presente.

Isso é particularmente útil quando a criação do valor padrão envolve uma computação custosa, uma chamada de método ou a obtenção de recursos externos, pois evita a execução desnecessária dessa computação se o valor dentro do Optional já estiver presente.

Exemplo de uso do orElseGet:


Optional<String> optionalValue = Optional.ofNullable(someValue);
String result = optionalValue.orElseGet(() -> computeDefaultValue());

Escolhendo entre orElse e orElseGet

A escolha entre orElse e orElseGet depende das necessidades específicas do cenário em que estão sendo usados. Em geral:

  • Use orElse quando o valor padrão é constante ou de fácil acesso e não envolve computação adicional.
  • Use orElseGet quando o valor padrão envolve computação custosa, chamadas de método ou obtenção de recursos externos, para evitar cálculos desnecessários quando o valor dentro do Optional já está presente.

Conclusão

Os métodos orElse e orElseGet da classe Optional em Java fornecem maneiras seguras e flexíveis de recuperar valores padrão quando o valor dentro do Optional não está presente. A diferença entre eles reside na forma como o valor padrão é fornecido: orElse usa um valor diretamente, enquanto orElseGet utiliza um Supplier, permitindo a computação tardia do valor apenas quando necessário. Escolher o método adequado depende da natureza do valor padrão e das necessidades de desempenho da aplicação.

A utilização apropriada desses métodos pode melhorar a legibilidade do código e reduzir a incidência de NullPointerException, tornando o código mais robusto e seguro. É sempre recomendável usar Optional sempre que possível, especialmente quando se trabalha com APIs que podem retornar valores nulos.

Qual a diferença entre orElse e orElseGet no Java Optional?

A principal diferença entre orElse e orElseGet no Java Optional é quando o valor padrão é avaliado. Com orElse(defaultValue), o defaultValue é sempre avaliado, independentemente de o Optional conter um valor ou não. Com orElseGet(() -> defaultValue), o Supplier que fornece o defaultValue só é invocado quando o Optional está vazio. Use orElseGet quando a criação do valor padrão for computacionalmente custosa.

Quando usar orElse em vez de orElseGet em Java?

Use orElse quando o valor padrão é constante, simples ou já está disponível (como literais ou variáveis já definidas), e sua avaliação não envolve custos significativos. Por exemplo: optional.orElse("valor padrão") ou optional.orElse(DEFAULT_CONSTANT).

Quando usar orElseGet em vez de orElse em Java?

Use orElseGet quando o valor padrão requer uma operação dispendiosa, como uma chamada de método, acesso a banco de dados, cálculos complexos ou criação de objetos. O orElseGet utiliza lazy evaluation, significando que a operação só é executada se o Optional estiver vazio. Por exemplo: optional.orElseGet(() -> databaseCall()) ou optional.orElseGet(() -> complexCalculation()).

O que acontece se eu usar orElse com uma chamada de método em Java?

Se você usar orElse com uma chamada de método, como optional.orElse(createExpensiveObject()), o método createExpensiveObject() será sempre executado, mesmo quando o Optional já contém um valor. Isso pode causar problemas de desempenho e efeitos colaterais indesejados. Nestes casos, é recomendado usar orElseGet(() -> createExpensiveObject()) para garantir que o método só seja chamado quando necessário.