El SayHello
es una interfaz de método abstracto único que tiene un método que toma una cadena y devuelve vacío. Esto es análogo a un consumidor. Solo está proporcionando una implementación de ese método en forma de consumidor que es similar a la siguiente implementación anónima de clase interna.
SayHello sh = new SayHello() {
@Override
public void speak(String message) {
System.out.println("Hello " + message);
}
};
names.forEach(n -> sh.speak(n));
Afortunadamente, su interfaz tiene un método único para que el sistema de tipos (más formalmente, el algoritmo de resolución de tipos) pueda inferir su tipo como SayHello
. Pero si tuviera 2 o más métodos, esto no sería posible.
Sin embargo, un enfoque mucho mejor es declarar al consumidor antes del ciclo for y usarlo como se muestra a continuación. Declarar la implementación para cada iteración crea más objetos de los necesarios y me parece contra-intuitivo. Aquí está la versión mejorada usando referencias de métodos en lugar de lambda. La referencia del método acotado utilizada aquí llama al método relevante en la hello
instancia declarada anteriormente.
SayHello hello = message -> System.out.println("Hello " + message);
names.forEach(hello::speak);
Actualizar
Dado que para lambdas apátridas que no capturan nada de su alcance léxico solo una vez que se creará una instancia, ambos enfoques simplemente crean una instancia de la SayHello
, y no hay ninguna ganancia siguiendo el enfoque sugerido. Sin embargo, esto parece ser un detalle de implementación y no lo sabía hasta ahora. Por lo tanto, un enfoque mucho mejor es simplemente pasar a un consumidor a su ForEach como se sugiere en el comentario a continuación. También tenga en cuenta que todos estos enfoques crean solo una instancia de su SayHello
interfaz, mientras que la última es más sucinta. Así es como se ve.
names.forEach(message -> System.out.println("Hello " + message));
Esta respuesta te dará más información sobre eso. Aquí está la sección relevante de JLS §15.27.4 : Evaluación en tiempo de ejecución de expresiones lambda
Estas reglas están destinadas a ofrecer flexibilidad a las implementaciones del lenguaje de programación Java, en el sentido de que:
- No es necesario asignar un nuevo objeto en cada evaluación.
De hecho, inicialmente pensé que cada evaluación crea una nueva instancia, lo cual está mal. @ Holger, gracias por señalarlo, buena captura.