How to use Lamda expressions – Part 1- What are lamda expressions?

Lamda expressions were introducted in Java 8.

They were out of the box , Java programmers weren’t used to anything like this before.

So getting adapted to it and start using it need some practise.

Once you understand lamda expressions you can super charge your programming skills and become a Super Hero.

Ok I am exaggerating.

But I was excited to discover this , so pardon me.

Getting back to lamdas,

Lamda expressions allow you to pass functions as arguments.

Java developers like me are used to pass arguments to functions.

What is this functions as arguments?

It totally confused me at first.

But after learning it , I quite like it.

Here is a simple explanation.

Consider a simple function to add two numbers:

class MathOperations{

public int sum(int a, int b){

return a+b;

}

}

If you want to add two numbers you need to :

1)Create an instance of the above class

2) Invoke the method sum() on the instance using the two parameters

MathOperations operations = new MathOperations();
operations.sum(5,8);

Now assume that you dont have to create the method sum() with the implementation of addition operation itself and still do the addition!

And using an expression like this as an argument to a function:

(a,b) -> return a+b

The above expression is a lamda expression. The expression before the arrow denote the inputs to a nameless function and the expression after the arrow is the body of the nameless function.

It is in fact a function implementation , you can treat this functionality as if it is just an argument to a method.

You can pass this functionality as an argument , to a method which takes a functional interface as an argument.

What is a functional interface? It is an interface with a single method.

Lamda expressions can be used to provide an implementation for functional interfaces. This implementation can then be passed as an argument.

Lamda expressions allow you to treat code like data.

Let’s see an example.

Java 8 gave us some inbuilt functional interfaces like Predicate<T>, Function<T,R> , Consumer<T> , Supplier<T>.

Let’s use one of this functional interfaces and lamda expressions to perform the above addition operation and see how it allows us to pass functionality as an argument.

Consider the below code :

class MathOperations{

public int performOperation(Input input, Function<Input,Integer> lamdaExpression){
   

    return lamdaExpression.apply(input);

}

}

In the above code Input is a class which has two attributes ‘a’ and ‘b’.

No addition operation is performed in the above code. And this same code can be used to perform any operation which takes two integers as arguments and returns an integer response.

class Input{

int a ;

int b;


public int getA(){return a;}
public int getB(){return b;}

public void setA(int a){
  this.a = a;
}

public void setB(int b){

   this.b = b;

}


}

Function<Input,Integer> is an inbuilt functional interface provided by Java . It has generic arguments (Function<T,R>). And it has one method apply(T) which takes an input T and returns the response R:

public R apply(T t);

So if you were to implement this functional interface yourself , you could do something like this:

Create a class SumOperation and implement the method apply():

public class SumOperation implements Function<Input,Integer>{


public Integer apply(Input input){

   return input.getA() + input.getB();

}

}

To call the above method in our client code , we can do this:

class Client{


 public static void main(String a[]){


   MathOperations operations= new MathOperations();

   Input input = new Input();
   input.setA(5);
   input.setB(8);

  int sum = operations.performOperations(input,new SumOperation());

}

}

Now let’s take help of lamda expressions. We can avoid the class SumOperation() altogether if we were to use lamda expressions like this :

class Client{


 public static void main(String a[]){


   MathOperations operations= new MathOperations();

   Input input = new Input();
   input.setA(5);
   input.setB(8);

  int sum = operations.performOperations(input,i -> return i.getA() + i.getB());

}

}

The expression i -> return i.getA() + i.getB() is a lamda expression.

It does the actual addition and we are passing this code as an argument to the method performOperations().

This is possible because the method peformOperations() takes an argument of a functional interface Function<T,R> which has only one method apply().

The lamda expression is an implementation of this method which takes a single argument and returns a single response. We can decide to do anything with the two arguments and return any response.

Now imagine the same performOperations() method can be used to do multiplication between two integers or division with two integers and so on. No need to create separate methods for each operation! We are deciding on the implementation at run time using lamda expressions!

Here is an example of performing multiplication between two integers using the same method performOperations() from MathOperations class:

class Client{


 public static void main(String a[]){


   MathOperations operations= new MathOperations();

   Input input = new Input();
   input.setA(5);
   input.setB(8);

  int multiplyResult= operations.performOperations(input,i -> return i.getA() * i.getB());

}

}

Less code . Dynamic implementation.

A little complicated to understand , but exciting to use once you learn it!

I felt the real benefit of lamda expressions while experimenting with a use case which is explained here:


Posted

in

by

Comments

Leave a Reply

Discover more from The Full Stack Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading