As expressões Lambda não alteram o conjunto de problemas que você pode resolver com Java em geral, mas definitivamente facilitam a solução de certos problemas, apenas pelo mesmo motivo de não estarmos mais programando em linguagem assembly. A remoção de tarefas redundantes do trabalho do programador facilita a vida e permite fazer coisas que você nem tocaria de outra maneira, apenas pela quantidade de código que você precisaria produzir (manualmente).
Mas expressões lambda não estão apenas salvando linhas de código. Expressões lambda permitem definir funções , algo para o qual você poderia usar classes internas anônimas como uma solução alternativa antes, é por isso que você pode substituir classes internas anônimas nesses casos, mas não em geral.
Mais notavelmente, expressões lambda são definidas independentemente da interface funcional para a qual serão convertidas, portanto, não há membros herdados aos quais eles possam acessar; além disso, eles não podem acessar a instância do tipo que implementa a interface funcional. Dentro de uma expressão lambda this
e super
com o mesmo significado que no contexto circundante, consulte também esta resposta . Além disso, você não pode criar novas variáveis locais que sombream variáveis locais do contexto circundante. Para a tarefa pretendida de definir uma função, isso remove muitas fontes de erro, mas também implica que, para outros casos de uso, pode haver classes internas anônimas que não podem ser convertidas em uma expressão lambda, mesmo se estiver implementando uma interface funcional.
Além disso, a construção new Type() { … }
garante produzir uma nova instância distinta (como new
sempre). Instâncias anônimas de classe interna sempre mantêm uma referência a sua instância externa, se criadas em um não static
contexto. Por outro lado, as expressões lambda capturam apenas uma referência this
quando necessário, ou seja, se elas acessam this
ou não são static
membros. E eles produzem instâncias de uma identidade intencionalmente não especificada, o que permite que a implementação decida em tempo de execução se deve reutilizar instâncias existentes (consulte também “ Uma expressão lambda cria um objeto no heap toda vez que é executado? ”).
Essas diferenças se aplicam ao seu exemplo. Sua construção anônima de classe interna sempre produzirá uma nova instância, também poderá capturar uma referência à instância externa, enquanto sua (Developer o1, Developer o2) -> o1.getName().compareTo(o2.getName())
é uma expressão lambda não capturadora que será avaliada para um singleton em implementações típicas. Além disso, ele não produz um .class
arquivo no seu disco rígido.
Dadas as diferenças em termos de semântica e desempenho, as expressões lambda podem mudar a maneira como os programadores resolverão certos problemas no futuro, é claro, também devido às novas APIs que abraçam idéias de programação funcional utilizando os novos recursos da linguagem. Consulte também expressão lambda do Java 8 e valores de primeira classe .
(o1, o2) -> o1.getName().compareTo(o2.getName())