Pesquisar este blog

quinta-feira, 9 de outubro de 2014

Evitando NullpointerException no Java 8 com Optional Funcional

Neste post será apresentado uma maneira Funcional de como programar um Optional que é uma novidade do java 8

Usando o método map

O método map usa uma expressão Lâmbida para produzir um resultado. Um programador acostumado com as versões <8 do java, tende a utilizar o optional da seguinte maneira:
Optional<Integer> optIntValor = Optional.of(10);
Integer valor;
if(optIntValor.isPresent()){
   valor = optIntValor.get()*2;
} else {
   valor = 0;
}
O uso do if é bem comum na programação orientada a objetos, porém no java 8 é possível programar de uma maneira diferente, usando a programação funcional com as expressões Lâmbida. Para fazer a mesma coisa de uma maneira funcional usamos o seguinte código:
Optional<Integer> optIntValor = Optional.of(10);
Integer valor = optIntValor.map(vlr -> vlr*2).orElse(0);
O que deixa o código bem mais compacto e bem fácil de entender, o método map só é executado quando o Optional tiver um valor e quando ele for executado o seu valor será multiplicado por 2, senão o valor retornado será 0.

Usando o método flatMap

O método flatMap é bem parecido com o map, e seu uso se aplica quando temos dois opicionais.
Imagine uma estrutura de objetos de modelo da seguinte forma:
class Endereco  {
    public Optional<String> getComplemento() {
        return complemento;
    }

    private Optional<String> complemento;
    public Endereco(String rua, Optional<String> complemento){}
}
class Usuario{
    public Optional<Endereco> getEndereco() {
        return endereco;
    }

    private Optional<Endereco> endereco;
    public Usuario(String nome, Optional<Endereco>endereco) {}
}
Considerando que os seus constutores setem os valores corretamente. Para pegar umv valor do complemento do endereço, a partir de uma instancia da classe usuário, devemos passar por dois optionais:
Endereco end = new Endereco("rua",Optional.of("Bloco C 22"))  ;
        Usuario usuario = new Usuario("nome",Optional.of(end));
        Optional<Optional<String>> comp = usuario.getEndereco().map(endereco -> endereco.getComplemento());
E o resultado disto é produzir um objeto Optional do Optional, e para resgatarmos o seu valor teremos que fazer comp.get().get(), mas isso não parece ser algo muito útil.
O método flatMap serve exatamente para isso, nestes casos ele nivela o objeto, eliminando um dos Optionals.
 Optional<String> comp = usuario.getEndereco().flatMap(endereco -> endereco.getComplemento());
Agora o resultado do objeto é um Optional e podemos trabalhar com ele como foi mostrado aqui.
Caso qualquer uma das instâncias dos Optionals forem vazias, ele retornará um valor vazio.

Usando o método filter

O método filter, como o seu nome diz, serve para filtrar valores, imagine que você tem um Optional e gostaria de garantir que o valor contido nele seja maior do que 10, para isso basta usar o método filter
 optIntValor.filter(vlr -> vlr>10);
Caso o valor contido no objeto optIntValor seja menor ou igual a 10 ele irá retornar um optional vazio, do contrário ele irá retornar um optional com o valor que o optIntValor continha.

Nenhum comentário:

Postar um comentário