Erklärung der Lambda-Ausdrücke

Erklärung der Lambda-Ausdrücke


Ich habe Fragen zu Lambda-Ausdrücken und RxJava. Diese Fragen betreffen hauptsächlich ein unvollständiges Verständnis von Lambda-Ausdrücken oder RxJava. Ich werde versuchen, Lambda-Ausdrücke so einfach wie möglich zu erklären. RxJava werde ich separat beschreiben.


Lambda Expressions und RxJava


Was sind Lambda-Ausdrücke? Lambda-Ausdrücke sind „nur“ eine neue Art, dasselbe zu tun, was wir immer tun konnten, aber auf eine sauberere und weniger ausführliche neue Art, anonyme innere Klassen zu verwenden.


Eine anonyme innere Klasse in Java ist eine unbenannte Klasse. Sie sollte verwendet werden, wenn Sie Klassen- oder Schnittstellenmethoden überschreiben müssen. Eine anonyme innere Klasse kann aus einer Klasse oder Schnittstelle erstellt werden.


Zum Beispiel:


abstract class Animal { abstract void speak(); } Animal a = new Animal() { void speak() { System.out.println("Woff"); } }; 

Unter Android verwenden wir normalerweise eine anonyme innere Klasse als Listener, beispielsweise für Schaltflächen dieser Art:


 Button btn = findViewById(R.id.button); btn.setOnClickListener( new View.OnClickListener() { @Override public void onClick(final View view) { // Do some fancy stuff with the view parameter. } } ); 

Kommen wir zurück zu den Lambda-Ausdrücken. Dies ist der nächste Teil, der Teil des vorherigen Codes ist, der als anonyme innere Klasse betrachtet wird.


 new View.OnClickListener() { @Override public void onClick(final View view) { // Do some fancy stuff with the view parameter. } } 

Lambda-Ausdrücke können nur verwendet werden, wenn Sie höchstens eine Methode überschreiben müssen. Zum Glück enthält View.OnClickListener nur einen. Schauen Sie sich den Code unten an. Welchen Teil müssen wir Ihrer Meinung nach entfernen?


 new View.OnClickListener() { @Override public void onClick(final View view) { // Do some fancy stuff with the view parameter. } } 

Nachdem wir fast den gesamten Code entfernt haben, müssen wir -> hinzufügen, wie im folgenden Code. Die Eingabeparameteransicht kann innerhalb der Funktion auf die gleiche Weise wie zuvor verwendet werden.


 (view) -> { // Do some fancy stuff with the view parameter. } 

In einigen Fällen müssen Sie einem Parameter möglicherweise einen Typ hinzufügen. Wenn der Compiler dies nicht erraten kann, können Sie dies tun, indem Sie ihn vor dem Parameter hinzufügen:


 (View view) -> { // Do some fancy stuff with the view parameter. } 

Sie können auch mehrzeiligen Code verwenden:


 (view) -> { Intent intent = new Intent(context, AuthActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); view.getContext().startActivity(intent); } 

Wenn Sie eine Schnittstelle mit einer Methode haben, die zwei Parameter akzeptiert ...


 interface MyInterface { abstract void onMethod(int a, int b); } 

... der Lambda-Ausdruck sieht folgendermaßen aus:


 (a, b) -> { // Do some fancy stuff with the a and b parameter. } 

Wenn die Methode einen Rückgabetyp hat ...


 interface MySecondInterface { abstract int onSecondMethod(int a, int b); } 

... der Lambda-Ausdruck sieht folgendermaßen aus:


 (a, b) -> { return a + b; } 

Aber das ist noch nicht alles. Es gibt einige Sonderfälle, die den Code noch kleiner machen. Wenn Ihr Methodenkörper nur eine Codezeile enthält, können Sie die geschweiften Klammern {} entfernen. Wenn Sie geschweifte Klammern entfernen, müssen Sie auch das Semikolon entfernen, wobei Folgendes übrig bleibt:


 (a, b) -> return a + b 

Wir können noch etwas tun. Wenn wir nur eine Codezeile haben, kann der Compiler verstehen, ob der zurückgegebene Teil benötigt wird oder nicht, also können wir ihn so belassen:


 (a, b) -> a + b 

Wenn wir mehrzeiligen Code hätten, würde dies Folgendes bedeuten:


 (a, b) -> { a+=1; return a + b; } 

Was haben wir also getan? Wir haben das genommen:


 new MySecondInterface() { @Override public int onSecondMethod(final int a, final int b) { return a + b; } }; 

und machte daraus:


 (a, b) -> a + b 

Es gibt nur noch eins: Methodenreferenzen. Angenommen, wir haben nach wie vor eine Schnittstelle und eine Methode, die diese Schnittstelle als Parameter akzeptiert:


 public interface Callback { public void onEvent(int event); } public void myMethod(Callback callback){ } 

Ohne einen Lambda-Ausdruck würde es so aussehen:


 myMethod(new Callback() { @Override public void onEvent(final int state) { System.out.println(state); } }); 

Wenn wir wie zuvor einen Lambda-Ausdruck hinzufügen, erhalten wir Folgendes:


 myMethod(state -> System.out.println(state)); 

Das ist aber noch nicht alles. Wenn der verwendete Code einzeilig ist und die aufgerufene Funktion einen Parameter akzeptiert, können wir die Methodenreferenz in folgender Form übergeben:


 myMethod(System.out::println); 

Der Parameter wird automatisch übergeben, ohne dass ein weiterer Code erforderlich ist! Erstaunlich, oder? Ich hoffe du hast etwas Neues gelernt!

Source: https://habr.com/ru/post/de419395/


All Articles