Dies SayHello
ist eine Single Abstract Method-Schnittstelle mit einer Methode, die eine Zeichenfolge verwendet und void zurückgibt. Dies ist analog zu einem Verbraucher. Sie stellen lediglich eine Implementierung dieser Methode in Form eines Verbrauchers bereit, die der folgenden anonymen Implementierung der inneren Klasse ähnelt.
SayHello sh = new SayHello() {
@Override
public void speak(String message) {
System.out.println("Hello " + message);
}
};
names.forEach(n -> sh.speak(n));
Glücklicherweise verfügt Ihre Schnittstelle über eine einzige Methode, sodass das Typsystem (formeller der Typauflösungsalgorithmus) auf seinen Typ als schließen kann SayHello
. Aber wenn es zwei oder mehr Methoden geben würde, wäre dies nicht möglich.
Ein viel besserer Ansatz besteht jedoch darin, den Verbraucher vor der for-Schleife zu deklarieren und wie unten gezeigt zu verwenden. Das Deklarieren der Implementierung für jede Iteration erzeugt mehr Objekte als nötig und erscheint mir kontraintuitiv. Hier ist die erweiterte Version, die Methodenreferenzen anstelle von Lambda verwendet. Die hier verwendete beschränkte Methodenreferenz ruft die relevante Methode für die hello
oben deklarierte Instanz auf.
SayHello hello = message -> System.out.println("Hello " + message);
names.forEach(hello::speak);
Aktualisieren
Angesichts der Tatsache, dass für staatenlose Lambdas, die nur einmal eine Instanz aus ihrem lexikalischen Geltungsbereich erfassen, niemals eine Instanz erstellt wird, erstellen beide Ansätze lediglich eine Instanz von SayHello
, und es gibt keinen Gewinn, der dem vorgeschlagenen Ansatz folgt. Dies scheint jedoch ein Implementierungsdetail zu sein, und ich wusste es bis jetzt nicht. Ein viel besserer Ansatz ist es also, einen Verbraucher an Ihren forEach weiterzugeben, wie im Kommentar unten vorgeschlagen. Beachten Sie auch, dass alle diese Ansätze nur eine Instanz Ihrer SayHello
Benutzeroberfläche erstellen, während die letzte prägnanter ist. So sieht es aus.
names.forEach(message -> System.out.println("Hello " + message));
Diese Antwort gibt Ihnen mehr Einblick. Hier ist der relevante Abschnitt aus dem JLS §15.27.4 : Laufzeitauswertung von Lambda-Ausdrücken
Diese Regeln sollen Implementierungen der Java-Programmiersprache Flexibilität bieten, indem:
- Ein neues Objekt muss nicht bei jeder Bewertung zugewiesen werden.
Tatsächlich dachte ich anfangs, dass jede Bewertung eine neue Instanz erstellt, was falsch ist. @ Holger danke für den Hinweis, guter Fang.