Explicação das expressões lambda

Explicação das expressões lambda


Eu tenho perguntas sobre expressões lambda e RxJava. Essas perguntas dizem respeito principalmente a um entendimento incompleto de expressões lambda ou RxJava. Vou tentar explicar as expressões lambda da maneira mais simples possível. RxJava vou descrever separadamente.


Expressões Lambda e RxJava


O que são expressões lambda? As expressões lambda são “apenas” uma nova maneira de fazer a mesma coisa que sempre poderíamos fazer, mas de uma maneira mais limpa e menos detalhada de usar classes internas anônimas.


Uma classe interna anônima em Java é uma classe sem nome; deve ser usada se você precisar substituir os métodos de classe ou interface. Uma classe interna anônima pode ser criada a partir de uma classe ou interface.


Por exemplo:


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

No Android, geralmente usamos uma classe interna anônima como ouvinte, por exemplo, para botões desse 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. } } ); 

Vamos voltar às expressões lambda. Esta é a próxima parte, que faz parte do código anterior, considerado uma classe interna anônima.


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

Expressões lambda só podem ser usadas se você precisar substituir no máximo um método. Felizmente para nós, o View.OnClickListener contém apenas um. Dê uma olhada no código abaixo. Que parte você acha que precisamos remover?


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

Depois de remover quase todo o código, precisamos adicionar ->, como no código abaixo. A visualização do parâmetro de entrada pode ser usada dentro da função da mesma maneira que antes.


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

Em alguns casos, pode ser necessário adicionar um tipo a um parâmetro; se o compilador não conseguir adivinhar, você poderá fazer isso adicionando-o antes do parâmetro:


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

Você também pode usar o código de várias linhas:


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

Se você possui uma interface com um método que aceita dois parâmetros ...


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

... a expressão lambda ficará assim:


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

Se o método tiver um tipo de retorno ...


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

... a expressão lambda ficará assim:


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

Mas isso não é tudo, existem alguns casos especiais que tornam o código ainda menor. Se o corpo do método contiver apenas uma linha de código, você poderá remover os chavetas {} . Se você remover chaves, também precisará remover o ponto-e-vírgula, deixando o seguinte:


 (a, b) -> return a + b 

Há mais uma coisa que podemos fazer. Se tivermos apenas uma linha de código, o compilador poderá entender se a parte retornada é necessária ou não, para que possamos deixar assim:


 (a, b) -> a + b 

Se tivéssemos código com várias linhas, ele se resumiria ao seguinte:


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

Então o que fizemos? Tomamos isso:


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

e transformou-o neste:


 (a, b) -> a + b 

Resta apenas uma coisa: referências de método. Suponha que tenhamos uma interface, como antes, e um método que aceite essa interface como parâmetro:


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

Sem uma expressão lambda, ficaria assim:


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

Adicionando uma expressão lambda, como fizemos anteriormente, obtemos o seguinte:


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

Mas isso não é tudo. Se o código usado for de linha única e a função chamada tiver um parâmetro, podemos passar a referência do método neste formato:


 myMethod(System.out::println); 

O parâmetro será passado automaticamente, sem a necessidade de outro código! Incrível né? Espero que você tenha aprendido algo novo!

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


All Articles