Está usando expressões lambda sempre que possível na boa prática de java?

52

Eu recentemente domeei a expressão Lambda que foi introduzida no java 8. Descobri que sempre que estou usando uma interface funcional, costumo usar sempre uma expressão do Lambda em vez de criar uma classe que implemente a interface funcional.

Isso é considerado boa prática? Ou são suas situações em que o uso de um Lambda para uma interface funcional não é apropriado?

    
por SteelToe 27.01.2017 / 16:40
fonte

5 respostas

112

Existem vários critérios que devem fazer você considerar não usar um lambda:

  • Tamanho Quanto maior o lambda, mais difícil é seguir a lógica que o envolve.
  • Repetição É melhor criar uma função nomeada para lógica repetida, embora seja correto repetir lambdas muito simples espalhados.
  • Nomeação Se você puder pensar em um ótimo nome semântico, você deve usá-lo, pois adiciona muita clareza ao seu código. Eu não estou falando de nomes como priceIsOver100 . x -> x.price > 100 é tão claro quanto esse nome. Quero dizer nomes como isEligibleVoter que substituem uma longa lista de condições.
  • Aninhamento Os lambdas aninhados são realmente muito difíceis de ler.

Não exagere. Lembre-se, o software é facilmente alterado. Em caso de dúvida, escreva nos dois sentidos e veja qual é mais fácil de ler.

    
por 27.01.2017 / 17:42
fonte
14

Depende. Sempre que você se encontrar usando o mesmo lambda em lugares diferentes, você deve considerar a implementação de uma classe que implemente a interface. Mas se você tivesse usado uma classe interna anônima, caso contrário, acho que um lambda é muito melhor.

    
por 27.01.2017 / 17:01
fonte
13

Eu apoio a resposta de Karl Bielefeldt, mas quero fornecer uma breve adição.

  • Depuração Alguns IDEs lutam com o escopo dentro de um lambda e lutam para exibir variáveis de membro dentro do contexto de um lambda. Enquanto esperamos que esta situação mude a linha, pode ser chato manter o código de outra pessoa quando ela estiver cheia de lambdas.
por 27.01.2017 / 20:39
fonte
5

Acesso a variáveis locais do escopo incluído

A Resposta aceita por Karl Bielefeldt aceita está correta. Eu posso adicionar mais uma distinção:

  • Escopo

O código lambda aninhado dentro de um método dentro de uma classe pode acessar qualquer variável final encontrada dentro desse método & classe.

A criação de uma classe que implemente a interface funcional não oferece acesso direto ao estado do código de chamada.

Para cite o Java Tutorial (grifo meu) :

Like local and anonymous classes, lambda expressions can capture variables; they have the same access to local variables of the enclosing scope. However, unlike local and anonymous classes, lambda expressions do not have any shadowing issues (see Shadowing for more information). Lambda expressions are lexically scoped. This means that they do not inherit any names from a supertype or introduce a new level of scoping. Declarations in a lambda expression are interpreted just as they are in the enclosing environment.

Portanto, embora haja benefícios em extrair o código longo e nomeá-lo, você deve ponderar isso com a simplicidade do acesso direto ao estado do método de inclusão & classe.

Veja:

por 28.01.2017 / 22:33
fonte
4

Isso pode ser difícil, mas para todos os outros pontos excelentes feitos em outras respostas, eu acrescentaria:

Preferir referências de método quando possível. Comparar:

employees.stream()
         .map(Employee::getName)
         .forEach(System.out::println);

versus

employees.stream()
         .map(employee -> employee.getName())
         .forEach(employeeName -> System.out.println(employeeName));

Usar uma referência de método evita a necessidade de nomear o (s) argumento (s) do lambda, que geralmente é redundante e / ou leva a nomes preguiçosos como e ou x .

    
por 08.02.2017 / 02:04
fonte

Tags