Wednesday 30 July 2014

Lambda Expressions in Java

Lambda expressions is a new feature included in Java SE 8. Lambda Expressions provide a way to represent functional interface using an expression.

A Functional interface is the one which has only one abstract method. The method declared in functional interface must not a public member of Object class.

For more information on Functional interface read the below link.

will try to implement all Arithmetic operations using Anonymous classes first and see How can we modify the same program using Lambda Expressions.

public interface Operation {
    int operation(int var1, int var2);
}

public class OperationTest {
    public static void main(String args[]){
        Operation add = new Operation(){
            public int operation(int a, int b){
                return (a+b);
            }
        };
        
        Operation subtract = new Operation(){
            public int operation(int a, int b){
                return (a-b);
            }
        };
        
        Operation multiply = new Operation(){
            public int operation(int a, int b){
                return (a*b);
            }
        };
        
        
        Operation divide = new Operation(){
            public int operation(int a, int b){
                return (a/b);
            }
        };
        
        Operation remainder = new Operation(){
            public int operation(int a, int b){
                return (a%b);
            }
        };
        
        System.out.println("Sum of 11 and 5 is " +add.operation(11, 5));
        System.out.println("Subtraction of 11 and 5 is " +subtract.operation(11, 5));
        System.out.println("Multiplication of 11 and 5 is " +multiply.operation(11, 5));
        System.out.println("Division of 11 and 5 is " +divide.operation(11, 5));
        System.out.println("Remainder of 11 and 5 is " +remainder.operation(11, 5));
        
    }
}

Output
Sum of 11 and 5 is 16
Subtraction of 11 and 5 is 6
Multiplication of 11 and 5 is 55
Division of 11 and 5 is 2
Remainder of 11 and 5 is 1

Will update the same program using Lambda Expressions.
public class OperationTest {
    public static void main(String args[]){
        Operation add = (int a, int b) -> {return (a+b);};
        Operation subtract = (int a, int b) -> {return (a-b);};
        Operation multiply = (int a, int b) -> {return (a*b);};
        Operation divide = (int a, int b) -> {return (a/b);};
        Operation remainder = (int a, int b) -> {return (a%b);};
        
        System.out.println("Sum of 11 and 5 is " +add.operation(11, 5));
        System.out.println("Subtraction of 11 and 5 is " +subtract.operation(11, 5));
        System.out.println("Multiplication of 11 and 5 is " +multiply.operation(11, 5));
        System.out.println("Division of 11 and 5 is " +divide.operation(11, 5));
        System.out.println("Remainder of 11 and 5 is " +remainder.operation(11, 5));
        
    }
}

Output
Sum of 11 and 5 is 16
Subtraction of 11 and 5 is 6
Multiplication of 11 and 5 is 55
Division of 11 and 5 is 2
Remainder of 11 and 5 is 1

As you observe anonymous class

Operation add = new Operation(){
                                  public int operation(int a, int b){
                                  return (a+b);
                              }
                          };

           is replaced with

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

Lambda Expression Syntax
Lambda Expression is composed of three parts.
  1. Argument List
  2. Arrow Token
  3. Body
In the Above program, addition function written like below.
Operation add = (int a, int b) -> (a+b);
  1. Argument List is (int a, int b)
  2. Arrow Token is ->
  3. Body is (a+b)
The body can be either a single expression or a statement block. In the expression form, the body is simply evaluated and returned.

We can re write the above program in expression form, since it has only one statement.
public class OperationTest {
    public static void main(String args[]){
        Operation add = (int a, int b) -> (a+b);
        Operation subtract = (int a, int b) -> (a-b);
        Operation multiply = (int a, int b) -> (a*b);
        Operation divide = (int a, int b) -> (a/b);
        Operation remainder = (int a, int b) -> (a%b);
        
        System.out.println("Sum of 11 and 5 is " +add.operation(11, 5));
        System.out.println("Subtraction of 11 and 5 is " +subtract.operation(11, 5));
        System.out.println("Multiplication of 11 and 5 is " +multiply.operation(11, 5));
        System.out.println("Dicision of 11 and 5 is " +divide.operation(11, 5));
        System.out.println("Remainder of 11 and 5 is " +remainder.operation(11, 5));
        
    }
}

In the block form (like {}), the body is evaluated like a method body and a return statement returns control to the caller of the method. 


You can omit the data types in Argument List section.

Operation add = (int a, int b) -> (a+b);

Above statement can be written as

Operation add = (a, b) -> (a+b);

public class OperationTest {
    public static void main(String args[]){
        Operation add = (a, b) -> {return (a+b);};
        Operation subtract = (a, b) -> {return (a-b);};
        Operation multiply = (a, b) -> {return (a*b);};
        Operation divide = (a, b) -> {return (a/b);};
        Operation remainder = (a, b) -> {return (a%b);};
        
        System.out.println("Sum of 11 and 5 is " +add.operation(11, 5));
        System.out.println("Subtraction of 11 and 5 is " +subtract.operation(11, 5));
        System.out.println("Multiplication of 11 and 5 is " +multiply.operation(11, 5));
        System.out.println("Division of 11 and 5 is " +divide.operation(11, 5));
        System.out.println("Remainder of 11 and 5 is " +remainder.operation(11, 5));
        
    }
}


Local variable reference from lambda expression must be final (or) effectively final. A variable or parameter whose value is never changed after it is initialized is effectively final.

public class Test {
 interface Operation {
  void operation();
 }

 public static void main(String... args) {
  int val = 10;

  Operation add = () -> {
   System.out.println(val);
  };

  val = 20;
 }

}

When you try to compile above program, you will get following error, since val is not a final variable (or) effectively final variable.

$ javac Test.java
Test.java:11: error: local variables referenced from a lambda expression must be final or effectively final
                           System.out.println(val);
                                              ^

1 error



Prevoius                                                 Next                                                 Home

No comments:

Post a Comment