2014-06-30 11 views
61

IntelliJ schlägt mir vor, meine Lambda-Ausdrücke durch Methodenreferenzen zu ersetzen.Lambda-Ausdruck vs Methodenreferenz

Gibt es einen objektiven Unterschied zwischen beiden?

+1

Es sind genau die gleichen Dinge, aber finden Sie nicht so etwas wie 'files.stream(). Map (File :: getName)'? –

+4

Nicht wirklich, ich sehe kein Objekt!Es sieht aus wie ein statischer Anruf zu mir – Gerard

+0

"sieht aus wie" ist kein Argument hier, denke ich. –

Antwort

7

Lange Lambda-Ausdrücke, die aus mehreren Anweisungen bestehen, können die Lesbarkeit Ihres Codes reduzieren. In einem solchen Fall könnte es besser sein, diese Anweisungen in einer Methode zu extrahieren und darauf zu verweisen. Der andere Grund kann sein Wiederverwendbarkeit. Anstatt & Ihren Lambda-Ausdruck einiger Anweisungen einzufügen, können Sie eine Methode konstruieren und sie von verschiedenen Stellen Ihres Codes aus aufrufen.

+1

Vergleiche: 'houses.map (House :: getName)' und 'houses.map (h -> h.getName())'. Das Lambda benötigt zwei weniger Zeichen. Es stimmt, dass der Typ nicht explizit ist, aber jede IDE würde es Ihnen sagen, und außerdem sollten lambdas verwendet werden, wenn der Typ offensichtlich ist. Ich kann Ihnen mit der Wiederverwendbarkeit zustimmen, aber Lambda sind genau winzig, so dass sie verkettet werden können, anstatt große spezifische Methoden zu erstellen. In diesem Sinne sind kleine Methoden wiederverwendbarer als einige große und komplexe Methoden, und aufgrund der Klarheit von Lambdas (und zu einem gewissen Grad Ausführlichkeit) sind sie immer noch leicht zu lesen. – Gerard

+8

Ich bin mit Gerald. Lesbarkeit leidet tatsächlich, wenn Sie Code ausziehen, also müssen Sie dazu springen, um weiter zu lesen, und dann zurück springen. Sie * wollen * alle relevanten Codes an der gleichen Stelle haben. Auch "House" ist ein sehr gutes Beispiel; Was ist mit 'ThreeStoryRedBrickHouseWithBlueDoors'. Ich bevorzuge Methodenverweise für Lambdas mit mehreren Argumenten, und manchmal betone ich, dass es sich bei Lambda nur um einen einzelnen Methodenaufruf handelt. Es gibt weniger Fehler mit einer Methodenreferenz: Sie könnten das Argument bei der Verwendung der Site falsch schreiben, indem Sie versehentlich auf eine Variable aus dem äußeren Bereich verweisen usw. –

+0

@Gerard Ich stimme Ihrer ersten Aussage nicht zu. Wenn Sie gut beschreibende Methodennamen verwenden und große Code-Stapel extrahieren, verbessert das Verschieben von Code die Lesbarkeit. Wenn Sie verschleiernde Methodennamen verwenden, stimme ich Ihnen zu. – Torsten

95

Diese Frage wird wahrscheinlich (und sollte) als primär auf Meinung beruhend eingestellt werden. Aber, bevor das passiert, lassen Sie mich einige Perspektive bieten, warum wir diese Funktion der Sprache hinzugefügt haben, wenn klar wir nicht unbedingt müssen (alle Methoden Refs können als Lambdas ausgedrückt werden.)

Beachten Sie, dass es gibt keine richtige Antwort. Jeder, der sagt "benutze immer einen Methodenref anstelle eines Lambdas" oder "verwende immer ein Lambda anstelle eines Methodenrefs", sollte ignoriert werden.

Diese Frage ist sehr ähnlich zu "wann sollte ich eine benannte Klasse vs anonyme Klasse verwenden"? Und die Antwort ist die gleiche: , wenn Sie es besser lesbar finden. Es gibt sicherlich Fälle, die definitiv eins oder definitiv das andere sind, aber es gibt eine Menge Grau in der Mitte, und das Urteil muss verwendet werden.

Die Theorie hinter Methode Refs ist einfach: Namen Angelegenheit. Wenn eine Methode einen Namen hat, dann ist es oft (aber nicht immer!) Klarer und lesbarer, wenn man sich auf den Namen und nicht auf einen Imperativ-Code bezieht, der sich schließlich umdreht und aufruft.

Die Argumente über die Leistung oder über das Zählen von Zeichen sind meist rote Heringe, und Sie sollten sie ignorieren. Das Ziel ist Code zu schreiben, der klar ist, was er tut. Sehr oft (aber nicht immer!) Methode Refs gewinnen auf dieser Metrik, so dass wir sie als eine Option enthalten, in diesen Fällen verwendet werden.

Eine wichtige Überlegung, ob Methodenrefs die Absicht verdeutlichen oder verschleiern, ist, ob es aus dem Kontext offensichtlich ist, wie die Form der dargestellten Funktion aussieht. In einigen Fällen (z. B. map(Person::getLastName)) ist es ziemlich klar aus dem Zusammenhang, dass eine Funktion, die eine Sache auf eine andere abbildet, erforderlich ist, und in solchen Fällen scheinen Methodenreferenzen. In anderen erfordert die Verwendung einer Methode Ref den Leser, sich zu fragen Art der Funktion wird beschrieben, das ist ein Warnzeichen, dass ein Lambda könnte besser lesbar sein, auch wenn es länger ist.

Schließlich haben wir festgestellt, dass die meisten Menschen zuerst wegsteuern von Methode Refs weil Sie fühlen sich noch neuer und seltsamer als Lambdas und finden sie daher anfänglich "weniger lesbar", aber im Laufe der Zeit, wenn sie sich an die Syntax gewöhnt haben, ändern sie im Allgemeinen ihr Verhalten und neigen zu Methodenverweisen, wenn sie können Die subjektiv initiale "weniger lesbare" Reaktion führt fast sicher zu einem gewissen Familienaspekt Sie sollten sich selbst eine Chance geben, sich mit beiden vertraut zu machen, bevor Sie eine stilistische Meinung abgeben.

+28

Ich fragte, ob es einen Unterschied gibt, nicht ob ich die eine oder andere Option verwenden sollte. – Gerard

+21

@Gerard Danke wäre eine bessere Antwort gewesen. –

+0

@Gerard Es klingt wie Brian sagt "Nein, da ist nicht" – dj18

Verwandte Themen