Com certeza você já precisou percorrer uma lista, invocando métodos em cada um dos objetos nela contidos, certo? Então, neste post vou te mostrar como o Lambda do Java 8 veio para ajudar, para facilitar esse tipo de situação.
Vou começar apresentando a ideia do projeto, fazendo da maneira pré Java 8, e depois acrescentar o Lambda para você ver como é simples entendê-lo. Mas não é só isso, vou aproveitar e te mostrar mais algumas novidades do Java 8, como a classe java.time.LocalDate, java.time.format.DateTimeFormatter e métodos default.
Temos um sistema financeiro que possui uma entidade Fatura. Que representa a fatura de uma determinada compra, que não vamos relacionar aqui para facilitar o exemplo. Veja o código dela abaixo:
package com.algaworks.modelo;
import java.time.LocalDate;
public class Fatura {
private String emailDevedor;
private double valor;
private LocalDate dataVencimento;
public Fatura(String emailDevedor, double valor, LocalDate dataVencimento) {
this.emailDevedor = emailDevedor;
this.valor = valor;
this.dataVencimento = dataVencimento;
}
// getters e setters
}
A ideia do sistema é, buscar as faturas vencidas e enviar um e-mail ao devedor lembrando-o sobre a dívida. Tarefa simples, não?
Para simplificar, não vou conectar no banco de dados, vamos apenas simular essa conexão já retornando uma lista com as faturas vencidas. Para isso, crie a classe FaturaDAO como abaixo:
package com.algaworks.dao;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import com.algaworks.modelo.Fatura;
public class FaturaDAO {
public List<Fatura> buscarFaturasVencidas() {
// Você iria no banco de dados...
Fatura f1 = new Fatura("joao@joao.com", 350.0, LocalDate.now().minusDays(3));
Fatura f2 = new Fatura("maria@maria.com", 150.0, LocalDate.now().minusMonths(2).minusDays(2));
Fatura f3 = new Fatura("jose@jose.com", 200.0, LocalDate.now().minusDays(5));
return Arrays.asList(f1, f2, f3);
}
}
Deixa eu te explicar o que significa a linha:
LocalDate.now().minusDays(3)
É tão simples quanto parece mesmo. Como eu não estou indo de fato no banco de dados, estou criando a classe Fatura com uma data passada, já vencida. Para isso eu utilizei o método now() de LocalDate para retornar a data de agora, logo em seguida o método minusDays(long diasASubtrair) subtrai 3 dias da data atual. Fala verdade, se fosse com Calendar daria um trabalho… :)
Agora que temos nosso modelo e a classe que os retorna do banco de dados, vamos criar uma classe que simulará o envio de e-mail. Mais uma vez vamos apenas simular o envio de e-mail, o objetivo aqui é mostrar o Lambda. Veja o código abaixo:
package com.algaworks.email;
public class EnviadorEmail {
public void enviar(String to, String text) {
// Aqui você utilizaria alguma biblioteca para enviar e-mail
System.out.printf("Enviando email para: %s. O Texto: %s\n", to, text);
}
}
Para passar o texto do e-mail, vamos criar um método resumo na classe Fatura que retorna o resumo da fatura, como a data de vencimento e o valor devido. Adicione o código abaixo:
public String resumo() {
String dataVencimento = this.dataVencimento.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
return String.format("Valor R$ %s, vencimento: %s", this.valor, dataVencimento);
}
Repare como ficou fácil formatar uma data. O DateTimeFormatter possui várias opções de formatação, mas você pode criar sua própria, usando o método ofPattern como fizemos acima.
Neste momento já temos tudo que precisamos para criar nossa classe de exemplo e eu finalmente te mostrar o Lambda em ação.
Crie a classe com.algaworks.exemplo.Exemplo com o método main e vamos começar a implementar a lógica de percorrer a lista e enviar os e-mails.
Veja abaixo como ficaria a implementação na forma tradicional:
public static void main(String[] args) {
EnviadorEmail enviadorEmail = new EnviadorEmail();
List<Fatura> faturasVencidas = new FaturaDAO().buscarFaturasVencidas();
for (Fatura f : faturasVencidas) {
enviadorEmail.enviar(f.getEmailDevedor(), f.resumo());
}
Tudo normal, certo? Então vamos começar a introduzir o Lambda de fato. Nós podemos substituir totalmente a linha que contém a instrução for. Pois foi adicionado um método em java.lang.Iterable chamado forEach. Veja a documentação java.lang.Iterable.
Se você viu a documentação, viu que é um novo método em uma interface o que poderia ser um grande problema, pois todas as classes deveriam ter que implementá-lo. Você estaria certo, se não fosse um detalhe, a palavra chave default adicionado na frente desse método. Agora a interface pode ter uma implementação, isso mesmo, interfaces podem ter implementação desde que o método seja marcado como default. Mais detalhes sobre isso vou deixar para um outro post.
Vamos seguir e substituir o for e utilizar o forEach. Traduza o forEach – para cada. Então pense assim, para cada elemento dentro da minha lista, faça alguma coisa. Veja o código abaixo:
faturasVencidas.forEach((Fatura f) -> {});
O que estou fazendo ali é a mesma coisa do for. O “f”, em Fatura f, recebe cada elemento da lista. Entre as chaves é onde vou colocar o código que quero executar, no nosso caso utilizar o objeto para enviar o e-mail. Ficando assim:
faturasVencidas.forEach((Fatura f) -> {
enviadorEmail.enviar(f.getEmailDevedor(), f.resumo());
});
Mas o compilador já sabe que sua lista é de Fatura. Então você pode omitir o tipo, deixando simplesmente assim:
faturasVencidas.forEach(f -> {
enviadorEmail.enviar(f.getEmailDevedor(), f.resumo());
});
E para melhorar ainda mais, como só temos uma linha de código para executar, podemos retirar as chaves e o ponto-e-vírgula de dentro do bloco. Veja:
faturasVencidas.forEach(f -> enviadorEmail.enviar(f.getEmailDevedor(), f.resumo()));
Muito simples! Te falei que seria simples de entender. :)
Se você tivesse que executar algum outro código e não somente uma linha, por exemplo, configurar uma variável dizendo que o e-mail foi enviado para você não enviar novamente. Poderia deixar o código como abaixo:
faturasVencidas.forEach(f -> {
enviadorEmail.enviar(f.getEmailDevedor(), f.resumo());
f.setNotificacaoEnviada(true);
});
É isso que gostaria de deixar para você.
Deixe seu comentário do que você achou da funcionalidade, se você achou realmente mais fácil.
Acesse ou baixe o código-fonte completo deste artigo no GitHub.
Para aprender mais sobre Java 8, conheça nosso curso online de Java e Orientação a Objetos, que é completo e substitui a necessidade de cursos presenciais.





Olá,
o que você achou deste conteúdo? Conte nos comentários.