Lambda expressions explained
I have gotten some questions about Lambda expressions and RxJava. These questions are mostly about not fully understanding Lambda expressions or RxJava. In this blog I will try to explain lambdas expressions as easy as I can. I will take the RxJava part in a separate blog.
Lambda expressions & RxJava
What is lambdas expressions? Lambda expressions is “only” a new way of doing the same thing we always been able to do but in a cleaner and less wordy the new way of on how to use anonymous inner classes.
An anonymous inner class in java is a class with no name, it should be used if you have to override methods of a class or interface. An anonymous inner class can be created from a class or interface.
Eg.
abstract class Animal {
abstract void speak();
}Animal a = new Animal() {
void speak() {
System.out.println("Woff");
}
};
In android we usually use anonymous inner class as listener for eg. buttons like this:
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.
}
}
);
So back to the lambda expressions. This is next part is the part of the previous code that is considered the 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 their is no more than one method you need to override. Lucky for us the View.OnClickListener only have one. Look at the code below especially the parts marked as bold. The bold part is the only part we should keep.
new View.OnClickListener() {
@Override
public void onClick(final View view) {
// Do some fancy stuff with the view parameter.
}
}
After removing all the non-bold code we only need to add the -> like in the code below. The incoming parameter view can be used inside the function just like before.
(view) -> {
// Do some fancy stuff with the view parameter.
}
In some cases you might need to add type to the parameter if the compiler don’t manage to guess it, you can do that by adding it in front of the parameter like this:
(View view) -> {
// Do some fancy stuff with the view parameter.
}
You can also have multiply lines of code like this:
(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 taking two parameters…
interface MyInterface {
abstract void onMethod(int a, int b);
}
…the lambda expression would look like this:
(a, b) -> {
// Do some fancy stuff with the a and b parameter.
}
If the method have a return type…
interface MySecondInterface {
abstract int onSecondMethod(int a, int b);
}
…the lambda expression would look like this:
(a, b) -> {
return a + b;
}
But this is not all there are some special cases that makes the code even less. If your method’s body only contain one line of code you can remove the curly brackets { }. If you remove the curly brackets you also need to remove the semicolon, leaving this:
(a, b) -> return a + b
There is one more thing we can do, if we only have one line of code the compiler can figure out if the return part is needed or not so we can leave it out like this:
(a, b) -> a + b
If it had multiply lines it would come down to this:
(a, b) -> {
a+=1;
return a + b;
}
So what have we done? We have taken this:
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 left, method references. Say I have an interface just like before and a method that take that interface as a parameter like this:
public interface Callback {
public void onEvent(int event);
}public void myMethod(Callback callback){
}
Without lambda it would look like this:
myMethod(new Callback() {
@Override
public void onEvent(final int state) {
System.out.println(state);
}
});
Adding the lambda as we already done would give us this:
MyMethod(state -> System.out.println(state));
But that is not all, if the code used is a one liner and a function call that takes one parameter we can use lambda method reference like this:
MyMethod(System.out::println);
The parameter will be passed thru automatic with no other code needed! Amazing, right? Hope you learned something new!