IntelliJ schlägt mir immer wieder vor, meine Lambda-Ausdrücke durch Methodenreferenzen zu ersetzen.
Gibt es einen objektiven Unterschied zwischen beiden?
java
intellij-idea
java-8
Gerard
quelle
quelle
Type[]::new
). Die zur Laufzeit generierte anonyme Klasse ist dieselbe. Die JRE macht keinen Unterschied zwischen ihnen. Wenn Sie also eine Methodenreferenz verwenden, sparen Sie eine Methode in Ihrem kompilierten Code. Andererseits können Sie beim schrittweisen Debuggen nicht bei ihnen stehen bleibenAntworten:
Lassen Sie mich eine Perspektive geben, warum wir diese Funktion zur Sprache hinzugefügt haben, obwohl dies eindeutig nicht unbedingt erforderlich war (alle Methodenreferenzen können als Lambdas ausgedrückt werden.)
Beachten Sie, dass es keine richtige Antwort gibt . Jeder, der sagt "Verwenden Sie immer eine Methodenreferenz anstelle eines Lambda" oder "Verwenden Sie immer ein Lambda anstelle einer Methodenreferenz", sollte ignoriert werden.
Diese Frage ist im Geiste sehr ähnlich zu "Wann sollte ich eine benannte Klasse gegen eine anonyme Klasse verwenden"? Und die Antwort ist dieselbe: Wenn Sie es besser lesbar finden . Es gibt sicherlich Fälle, die definitiv der eine oder andere sind, aber es gibt eine Menge Grau in der Mitte, und das Urteilsvermögen muss angewendet werden.
Die Theorie hinter den Methodenreferenzen ist einfach: Namen sind wichtig . Wenn eine Methode einen Namen hat, ist es oft (aber nicht immer!) Klarer und lesbarer, auf sie mit Namen zu verweisen, anstatt durch einen zwingenden Code-Beutel, der sich letztendlich nur umdreht und ihn aufruft.
Die Argumente zur Leistung oder zum Zählen von Zeichen sind meistens rote Heringe, und Sie sollten sie ignorieren. Das Ziel ist das Schreiben von Code, der kristallklar ist, was er tut. Sehr oft (aber nicht immer!) Gewinnen Methodenreferenzen für diese Metrik, daher haben wir sie als Option aufgenommen, um sie in diesen Fällen zu verwenden.
Eine wichtige Überlegung darüber, ob Methodenreferenzen die Absicht klarstellen oder verschleiern, ist, ob aus dem Kontext ersichtlich ist, welche Form die dargestellte Funktion hat. In einigen Fällen (z. B. ist
map(Person::getLastName)
aus dem Kontext ziemlich klar, dass eine Funktion erforderlich ist, die eine Sache einer anderen zuordnet, und in solchen Fällen leuchten Methodenreferenzen. In anderen Fällen muss sich der Leser bei Verwendung einer Methodenreferenz fragen, welche Art von Funktion verwendet wird Dies ist ein Warnsignal dafür, dass ein Lambda möglicherweise besser lesbar ist, auch wenn es länger ist.Schließlich haben wir festgestellt, dass die meisten Leute sich zunächst von Methodenreferenzen abwenden, weil sie sich noch neuer und seltsamer fühlen als Lambdas, und sie daher zunächst "weniger lesbar" finden, aber im Laufe der Zeit, wenn sie sich an die Syntax gewöhnen, Ändern Sie im Allgemeinen ihr Verhalten und tendieren Sie zu Methodenreferenzen, wenn sie können. Seien Sie sich also bewusst, dass Ihre subjektive anfängliche "weniger lesbare" Reaktion mit ziemlicher Sicherheit einen Aspekt der familiären Voreingenommenheit mit sich bringt, und Sie sollten sich die Möglichkeit geben, sich mit beiden vertraut zu machen, bevor Sie eine stilistische Meinung abgeben.
quelle
LiveData
innerhalb eines handeltFragment
, das ich in ein konvertiert habe,Event
das durch einViewModel
... ausgelöst wird, und das unterschiedliche Verhalten tritt auf, wenn Android zum selben zurückkehrtFragment
. .so fällt es mir schwer, es für eine Frage zu vereinfachenLange Lambda-Ausdrücke, die aus mehreren Anweisungen bestehen, können die Lesbarkeit Ihres Codes beeinträchtigen. In einem solchen Fall ist es möglicherweise besser, diese Anweisungen in einer Methode zu extrahieren und darauf zu verweisen.
Der andere Grund kann die Wiederverwendbarkeit sein . Anstatt Ihren Lambda-Ausdruck aus wenigen Anweisungen zu kopieren und einzufügen, können Sie eine Methode erstellen und von verschiedenen Stellen Ihres Codes aus aufrufen.
quelle
houses.map(House::getName)
undhouses.map(h -> h.getName())
. Das Lambda benötigt zwei Zeichen weniger. Es ist wahr, 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 stimme Ihnen vielleicht in Bezug auf die Wiederverwendbarkeit zu, aber Lambdas sind genau winzig, sodass sie verkettet werden können, anstatt große spezifische Methoden zu erstellen. In diesem Sinne sind kleine Methoden wiederverwendbarer als große und komplexe Methoden, und aufgrund der Klarheit von Lambdas (und bis zu einem gewissen Grad der Ausführlichkeit) sind sie immer noch leicht zu lesen.House
ist ein sehr gütiges Beispiel; was ist mitThreeStoryRedBrickHouseWithBlueDoors
. Ich bevorzuge Methodenreferenzen für Lambdas mit mehreren Argumenten und manchmal, um zu betonen, dass es sich bei dem Lambda nur um einen einzelnen Methodenaufruf handelt. Mit einer Methodenreferenz kann man weniger falsch machen: Sie können das Argument an der Verwendungsstelle falsch