📜 ⬆️ ⬇️

Explanation of lambda expressions

Explanation of lambda expressions


I have questions about lambda expressions and RxJava. These questions mainly concern incomplete understanding of lambda expressions or RxJava. I will try to explain the lambda expressions as simply as possible. I will describe RxJava separately.


Lambda expressions and rxjava


What is lambda expression? Lambda expressions are “just” a new way to do the same thing that we could always do, but in a cleaner and less verbose way of using anonymous inner classes.


An anonymous inner class in Java is an unnamed class; it must be used if you need to override the methods of a class or interface. An anonymous inner class can be created from a class or interface.


For example:


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

In Android, we usually use an anonymous inner class as a listener, for example, for buttons of this kind:


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

Let's return to lambda expressions. This is the next part, which is part of the previous code, which is considered an anonymous inner class.


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

Lambda expressions can only be used if you need to override no more than one method. Fortunately for us, View.OnClickListener contains only one. Look at the code below. What do you think, what part of it we have to remove?


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

After deleting almost all of the code, we need to add ->, as in the code below. The input parameter view can be used inside the function as before.


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

In some cases, you may need to add a type to a parameter, if the compiler cannot guess it, you can do this by adding it in front of the parameter:


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

You can also use multi-line code:


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

If you have an interface with a method that takes two parameters ...


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

... the lambda expression will look like this:


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

If the method has a return type ...


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

... the lambda expression will look like this:


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

But that's not all, there are some special cases that make the code even smaller. If the body of your method contains only one line of code, you can remove curly braces {} . If you remove braces, you also need to remove the semicolon, leaving the following:


 (a, b) -> return a + b 

There is one more thing we can do. If we have only one line of code, then the compiler can understand whether the return part is needed or not, so we can leave it as follows:


 (a, b) -> a + b 

If we had a multi-line code, it would be reduced to the following:


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

So what have we done? We took it:


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

and turned it into this:


 (a, b) -> a + b 

Only one thing remains, references to methods. Suppose we have an interface, as before, and a method that this interface takes as a parameter:


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

Without a lambda expression, it would look like this:


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

Adding a lambda expression, as we did before, we get the following:


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

But that is not all. If the code used is single-line and the called function takes one parameter, we can pass a reference to the method in this form:


 myMethod(System.out::println); 

The parameter will be transmitted automatically, without the need for another code! Amazing, right? I hope you learned something new!


')

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


All Articles