Monday, 11 August 2014

In Detail : Lambda Expressions In JAVA 8 - part 1

What Is A Lambda Expression ?
A Lambda Expression is an anonymous method, which is a compact way of passing around behavior as if it were data.

The code written using anonymous inner classes serves as data. These classes were designed to make it easier for Java programmers to pass around code as data.

Lambda Expressions are used to implement a method specified by a Functional Interface. Visit my previous post on Functional Interfaces from here, for video tutorial you can find here. Thus a Lambda Expression results in a form of anonymous class. There are also commonly referred as closures.

Writing The First Lambda Expression : 

As i have specified in my previous post on Functional Interfaces, Runnable is a Functional Interface in Java8. So before going to write our first lambda expression, lets see how to create a thread using anonymous inner classes.

public class AnonymousThread {

    public static void main(String[] args) {

      new Thread(new Runnable() {
      @Override
      public void run() {    
        System.out.println("This is anonymous thread");
      }   
     }).start();
   }

}

Here we are passing object , but we really need is to pass some behavior. This passing behavior can be achieved through lambda expressions. Now lets see how to use Lambda Expression to create a Thread. Below is the code.

 public class LambdaThread {
 
    public static void main(String[] args) {  
       new Thread(() -> System.out.println("This is lambda thread")).start();
    }
}

The difference here is with anonymous inner classes, it took 6 lines of code to create a thread, but with lambda expressions it took only 1 line of code. The code written using anonymous inner classes is hard to read because it obscures the programmer's intent. Even though there is no performance improvement in this case, but the code looks concise and it significantly streamlines your code base.



Understanding The Lambda Expression :

    Lambda Expressions introduced a new syntactic element and an operator into Java language. The new operator is "->", this is called as Lambda operator. This operator divides lambda expression into two parts, the left side of the operator is method signature and right side of the operator is method implementation.

on the left side i.e Method signature, you can specify parameters required and method implementation represents lambda body i.e body to the abstract method.

you can represent lambda body in two ways,

1. Lambda body which consists of single expression, also referred as expression lambdas.
2. The other consists of block of code.
Expression Lambdas :

   Consider, you have a functional interface which doesn't take any parameters but returns int, just like below.

package com.speakincs.funcinterfaces;

@FunctionalInterface
public interface SimpleFI {

    int randomNum(); 

} 

An expression lambda for this is

 SimpleFI sf = () -> 5;

The above lambda expression returns an integer. you don't have to use an explicit return keyword.

The above code is similar to the folowing method.

 int randomNum() { 
    return 5;
}

 Now consider, you have a functional interface which takes two integer arguments and returns sum of both.
 
package com.speakincs.funcinterfaces;

@FunctionalInterface
public interface Addition {
 
    public int sum(int a, int b); 
 
}

The parameterized expression lambda for this is

 Addition add = (a,b) -> return a+b; 
You don't have to declare types for the parameters, Under the hood java compiler is inferring the type of parameters from it's context i.e from signature of the method. Including type declarations can not result in compilation errors.

Block Lambda Expressions :

     If you need to write multiple statements in a lambda body include then in braces i.e '{' , '}' . Lambdas that have block bodies are some times referred as block lambdas.

In a block lambda you can declare variables, use loops, specify if , switch statements, create nested blocks and so on.

In block lambdas you must explicitly use a return statement to return a value. Lets see how to write for functional interface Addition.

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

How To Pass Lambda Expressions As Arguments :

    If necessary, you can also pass lambda expressions as arguments to a method, which means you are passing executable code as an argument.

The prerequisite for this is, the type of the parameter receiving the lambda expression argument must be of a functional interface type compatible with the lambda. Here is a simple program for this.

package com.speakincs.funcinterfaces;

public class FirstLambda {

    public static void main(String[] args) {
  
 createThread(() -> System.out.println("Lambda expression as argumetn"));

    }

    private static void createThread(Runnable r) {

  new Thread(r).start();
  
    }
 
}
 
Here we are passing lambda expression as an argument to the createThread() method.

What happens behind the scenes :

When ever you pass a lambda expression, behind the scenes an instance of the functional interface is created and a reference to that object is passed as an argument to the method. Thus lambda expression is embedded in a class instance and is passed to the method.

This technique is useful when you want the lambda expression is intended for a single use.

0 comments:

Post a Comment

Note: only a member of this blog may post a comment.