Explicaci贸n de expresiones lambda

Explicaci贸n de expresiones lambda


Tengo preguntas sobre expresiones lambda y RxJava. Estas preguntas se refieren principalmente a una comprensi贸n incompleta de las expresiones lambda o RxJava. Tratar茅 de explicar las expresiones lambda lo m谩s simple posible. RxJava lo describir茅 por separado.


Expresiones Lambda y RxJava


驴Qu茅 son las expresiones lambda? Las expresiones lambda son "simplemente" una nueva forma de hacer lo mismo que siempre podr铆amos hacer, pero en una nueva forma m谩s limpia y menos detallada de usar clases internas an贸nimas.


Una clase interna an贸nima en Java es una clase sin nombre, debe usarse si necesita anular la clase o los m茅todos de interfaz. Se puede crear una clase interna an贸nima desde una clase o interfaz.


Por ejemplo:


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

En Android, usualmente usamos una clase interna an贸nima como oyente, por ejemplo, para botones de este tipo:


 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. } } ); 

Volvamos a las expresiones lambda. Esta es la siguiente parte, que es parte del c贸digo anterior, que se considera una clase interna an贸nima.


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

Las expresiones lambda solo se pueden usar si necesita anular como m谩ximo un m茅todo. Afortunadamente para nosotros, View.OnClickListener contiene solo uno. Echa un vistazo al c贸digo a continuaci贸n. 驴Qu茅 parte crees que tenemos que eliminar?


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

Despu茅s de eliminar casi todo el c贸digo, necesitamos agregar ->, como en el siguiente c贸digo. La vista de par谩metros de entrada se puede usar dentro de la funci贸n de la misma manera que antes.


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

En algunos casos, es posible que deba agregar un tipo a un par谩metro, si el compilador no puede adivinarlo, puede hacerlo agreg谩ndolo antes del par谩metro:


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

Tambi茅n puede usar c贸digo de varias l铆neas:


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

Si tiene una interfaz con un m茅todo que toma dos par谩metros ...


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

... la expresi贸n lambda se ver谩 as铆:


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

Si el m茅todo tiene un tipo de retorno ...


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

... la expresi贸n lambda se ver谩 as铆:


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

Pero eso no es todo, hay algunos casos especiales que hacen que el c贸digo sea a煤n m谩s peque帽o. Si el cuerpo de su m茅todo contiene solo una l铆nea de c贸digo, puede eliminar las llaves {} . Si elimina llaves, tambi茅n debe quitar el punto y coma, dejando lo siguiente:


 (a, b) -> return a + b 

Hay una cosa m谩s que podemos hacer. Si solo tenemos una l铆nea de c贸digo, el compilador puede comprender si la parte devuelta es necesaria o no, por lo que podemos dejarla as铆:


 (a, b) -> a + b 

Si tuvi茅ramos c贸digo de varias l铆neas, se reducir铆a a lo siguiente:


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

Entonces, 驴qu茅 hemos hecho? Tomamos esto:


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

y lo convirti贸 en esto:


 (a, b) -> a + b 

Solo queda una cosa, referencias de m茅todos. Supongamos que tenemos una interfaz, como antes, y un m茅todo que acepta esta interfaz como par谩metro:


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

Sin una expresi贸n lambda, se ver铆a as铆:


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

Al agregar una expresi贸n lambda, como lo hicimos antes, obtenemos lo siguiente:


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

Pero eso no es todo. Si el c贸digo utilizado es de una sola l铆nea y la funci贸n llamada toma un par谩metro, podemos pasar la referencia del m茅todo de esta forma:


 myMethod(System.out::println); 

隆El par谩metro se pasar谩 autom谩ticamente, sin necesidad de otro c贸digo! Incre铆ble verdad? 隆Espero que hayas aprendido algo nuevo!

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


All Articles