A SayHello
é uma interface Single Abstract Method que possui um método que pega uma string e retorna nulo. Isso é análogo a um consumidor. Você está apenas fornecendo uma implementação desse método na forma de um consumidor semelhante à seguinte implementação de classe interna anônima.
SayHello sh = new SayHello() {
@Override
public void speak(String message) {
System.out.println("Hello " + message);
}
};
names.forEach(n -> sh.speak(n));
Felizmente, sua interface possui um método único para que o sistema de tipos (mais formalmente, o algoritmo de resolução de tipos) possa inferir seu tipo como SayHello
. Mas se tivesse dois ou mais métodos, isso não seria possível.
No entanto, uma abordagem muito melhor é declarar o consumidor antes do loop for e usá-lo como mostrado abaixo. Declarar a implementação para cada iteração cria mais objetos do que o necessário e parece contra-intuitivo para mim. Aqui está a versão aprimorada usando referências de método em vez de lambda. A referência do método limitado usada aqui chama o método relevante na hello
instância declarada acima.
SayHello hello = message -> System.out.println("Hello " + message);
names.forEach(hello::speak);
Atualizar
Dado que para lambdas sem estado que não captura nada do seu escopo lexical apenas uma vez que a instância é criada, ambas as abordagens simplesmente criam uma instância da SayHello
e não há nenhum ganho após a abordagem sugerida. No entanto, este parece ser um detalhe de implementação e eu não o conhecia até agora. Portanto, uma abordagem muito melhor é passar o consumidor para o seu forEach, conforme sugerido no comentário abaixo. Observe também que todas essas abordagens criam apenas uma instância da sua SayHello
interface, enquanto a última é mais sucinta. Aqui está como fica.
names.forEach(message -> System.out.println("Hello " + message));
Esta resposta lhe dará mais informações sobre isso. Aqui está a seção relevante do JLS §15.27.4 : Avaliação em tempo de execução de expressões lambda
Essas regras visam oferecer flexibilidade às implementações da linguagem de programação Java, na medida em que:
- Um novo objeto não precisa ser alocado em todas as avaliações.
De fato, inicialmente pensei que toda avaliação cria uma nova instância, o que está errado. @ Holger obrigado por apontar isso, boa captura.