Lambdas - F4NT0/J4V4 GitHub Wiki

Retornar

Lambdas

  • Lambda vem da Programação Funcional

  • Conceito adicionado no Java8

  • A grande vantagem de funções lambda é diminuir a quantidade de código necessária para escrever alguma função

  • Uma função lambda é uma função sem declaração(não é necessário um nome, tipo de retorno e o modificador de acesso)

  • A idéia é que o método seja declarado no mesmo lugar em que será usado

  • As funções lambdas em Java tem a sintaxe definica como:

    • (argumento) -> (corpo)
  • Existem tipos de Expressões Lambdas:

Tipo Descrição
Function Recebe um parâmetro e produz um resultado qualquer
Predicate Recebe um parâmetro e produz um booleano
BinaryOperator Recebe dois parâmetros do mesmo tipo e produz um resultado do mesmo tipo
Consumer Recebe um parâmetro e não produz resultado
Supplier Não recebe parâmetros e produz um resultado
  • Exemplo de Expressão Lambda Simples:
 (int a,int b) -> a + b; //TIPO DE EXPRESSÃO LAMBDA: BinaryOperator
 
 () -> new Object() // TIPO DE EXPRESSÃO LAMBDA: Supplier

 
(String s) -> {System.out.println(s);} //TIPO DE EXPRESSÃO LAMBDA: Consumer

(int x) -> x++; //TIPO DE EXPRESSÃO LAMBDA: Function

(double x, double y) -> x+y; //TIPO DE EXPRESSÃO LAMBDA: BinaryOperator

  • Uma função Lambda pode ter nenhum ou vários parâmetros
  • A função lambda pode ter nenhum ou vários comandos
  • Se tiver somente um comando, as chaves não são obrigatórias
  • Se nada for retornado a função retorna um void
  • Uma expressão Lambda resulta em um elemento manipulável

Threads

  • Threads são utilizadas para simplificar o código

  • Cada processo possui diversas threads(linhas de instruções)

  • Podemos dividir partes do nosso processo(Programa Java) para trabalhar paralelamente

  • Se voçê deseja que o programa não "trave o usuário" naquele determinado procedimento que pode demorar, Use threads

  • Como se usa:

    • Primeiro é criada uma implementação do método run da interface Runnable
    • Segundo é criada a Thread com essa implementação.
    • Com a expressão lambda, o código necessário para a implementação é bastante simples e menor
    • Ex:
Runnable r = () -> System.out.println("Thread com função Lambda!");
new Thread(r).start();
  • Essa expressão não passa nenhum parâmetro, pois ela será passada para a função run
  • Pode-se fazer também é passar a função diretamente como parâmetro para o construtor da classe Thread
  • Funções lambdas podem ser definidas e passadas como parâmetros diretamente para outros métodos
new Thread(() -> System.out.println("Hello World")).start();

Funções lambdas com Collections

  • Lambdas podem ser bastantes utilizadas com as classes de Coleções Java
  • Pode-se percorrer a coleção, fazer uma ação, filtrar elementos, etc...
  • Exemplo de como percorrer uma lista e imprimir os valores
  • Foi usado um ForEach para percorrer a lista
List<Integer> lista = Arrays.asList(1,2,3,4,5,6,7);
for(Integer n : lista){
    System.out.println(n);
}
  • Com as funções lambdas é possivel implementar a mesma funcionalidade com menos código
  • Basta chamar o método forEach de uma lista, que é um método que espera uma função lambda como parâmetro
  • Exemplo de uma impressão de elementos de uma lista com Lambda
List<Integer> lista = Arrays.asList(1,2,3,4,5,6,7);
lista.forEach(n -> System.out.println(n));
  • Dentro de uma expressão Lambda qualquer coisa pode ser usada
  • Pode-se extender uma expressão lambda com {}
  • Exemplo de imprimir valores pares de uma lista:
List<Integer> lista = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
lista.forEach(n -> {
    if(n % 2 == 0){
     System.out.println(n);
    }
});

Usando Lambdas com Objetos

  • Funções Lambdas podem ser utilizadas também para a ordenação de listas com a interface comparator
  • Podemos usar Lambdas com Objetos também
  • Exemplo de uma classe pessoa, onde coloca o nome e idade:
public class Pessoas{
    private String nome;
    private int idade;
    
    public Pessoas(String nome, int idade){
        this.nome = nome;
        this.idade = idade;
    }
    
    public String getNome(){return nome;}
    public int getIdade(){return idade;}
}
  • Se quisermos ordenar em ordem alfabética os nomes:
List<Pessoas> listaPessoas = Arrays.asList(new Pessoas("Gabriel",22),new Pessoas("Alexandre",30),new Pessoas("Douglas",22));
Collections.sort(listaPessoas,(Pessoas pessoa1,Pessoas pessoa2) -> {
    pessoa1.getNome().compareTo(pessoa2.getNome())
});
listaPessoas.forEach(p -> System.out.println(p.getNome()));
  • Se quisermos ordenar em ordem de idade:
List<Pessoas> listaPessoas = Arrays.asList(new Pessoas("Gabriel",22),new Pessoas("Alexandre",30),new Pessoas("Douglas",22));
Collections.sort(listaPessoas,(Pessoas pessoa1,Pessoas pessoa2) -> {
    pessoa1.getIdade().compareTo(pessoa2.getIdade())
});
listaPessoas.forEach(p -> System.out.println(p.getNome()))

Expressões Lambdas usando a API java.util.stream

  • Como exemplo iremos obter a maior nota de um estudante cujo ano de graduação for 2015

  • Utilizando o método privado .stream()

  • Utilizando o método privado .filter()

  • Utilizando o método privado .mapToDouble()

  • Utilizando o método privado .max()

  • RESOLUÇÃO:

public class Estudante{
  //Variaveis privada
  private String nome;
  private int anoGraduacao;
  private double nota;

 public Estudante(String n,int ano,double nota){
    nome = n;
    anoGraduacao = ano;
    this.nota = nota;
  }

  //Getters
  public String getNome(){return nome;}
  public int getAno(){return anoGraduacao;}
  public double getNota(){return nota;}
}
  • Código natural de resolução:
List<Estudante> estudantes = new ArrayList<>();
double maiorNota = 0.0;
//usando ForEach
for(Estudante estudante : estudantes){
  if(estudante.getAno() == 2015){
    if(estudante.getNota() > maiorNota){
      maiorNota = estudante.getNota();
    }
  }
}
  • Código usando Classes internas anônimas
List<Estudante> estudantes = new ArrayList<>();
double maiorNota
               = estudantes.stream().filter(new Predicate<Estudante>() {
                   @Override
                   public boolean test(Estudante estudante){
                      return estudante.getAno() == 2015;
                   }
               }).mapToDouble(new ToDoubleFunction<Estudante>() {
                   @Override
                   public double applyAsDouble(Estudante estudante){
                     return estudante.getNota();
                   }
               }).max().getAsDouble();
  • Agora código usando Expressões Lambdas:
List<Estudante> estudantes = new ArrayList<>();
double maiorNota = estudantes.stream()
      .filter(e -> e.getAno() == 2015)
      .mapToDouble(Estudante::getNota())
      .max().getAsDouble();
⚠️ **GitHub.com Fallback** ⚠️