Lambda Expressions – Syntax

In my last couple of posts, I talked about Need of Lambda Expressions and continued it in the next post. Now that we know why we need Lambda Expressions, we can move forward and have a look at how to use them. We need to look at the syntax and where and how to use them for better and short code.

First let’s have a look at what are Lambda Expressions. Lambda Expressions are like Anonymous Functions (which are like methods but without a class). They are ‘like’ methods but they really are not methods. That’s because they represent methods, but are not associated with any class. Hence we cannot call them methods. Se we choose the term Anonymous Functions.

(parameters) -> { lambda-body }

-> is the lambda operator. On the left side of the lambda operator, we have a comma-separated list of formal parameters enclosed in parentheses that we pass into the anonymous function. On the right hand side of the lambda operator is the body of the lambda expression. A body consists of a single expression or a statement block. This is the most basic syntax of Lambda Expressions.

Let’s see an example.

int prod = (int a, int b) -> { return a * b; };

In the above example, we have two int parameters that we pass into our anonymous function and it returns us their product which we store in an int variable prod. Now there are a few more things we need to know about the syntax.

  1. You can omit the data type of the parameters in a lambda expression. In addition, you can omit the parentheses if there is only one parameter.
  2. We don’t have to write the data types of the parameters. We can omit them, although its not mandatory.
  3. If you have a single line in body of the lambda expression, then you can omit the braces. Braces are option is such case. But braces are not optional in multi line body. Also if you explicitly write the return keyword, that makes it a statement.  In a lambda expression, you must enclose statements in braces.

Let’s see some examples to understand it properly

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class LambdaTest {
   public static void main(String args[]){
      LambdaTest tester = new LambdaTest();
 
      //with type declaration
      Operation addition = (int a, int b) -> a + b;
 
      //with out type declaration
      Operation subtraction = (a, b) -> a - b;
 
      //with return statement along with curly braces
      Operation multiplication = (int a, int b) -> { return a * b; };
 
      //without return statement and without curly braces
      Operation division = (int a, int b) -> a / b;
 
      System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
      System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
      System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
      System.out.println("10 / 5 = " + tester.operate(10, 5, division));
 
      //We can directly pass in lambda expressions where the interface is needed.
      System.out.println("Direct 10 + 5 = " + tester.operate(10, 5, (int a, int b) -> a + b);
 
      //with parenthesis
      GreetingService greetService1 = message ->
      System.out.println("Hello " + message);
 
      //without parenthesis
      GreetingService greetService2 = (message) ->
      System.out.println("Hello " + message);
 
      greetService1.sayMessage("Mahesh");
      greetService2.sayMessage("Suresh");
 
      SayHello sayHello = () -> System.out.println("Hello");
      sayHello.sayHelloMethod();
   }
 
   interface Operation {
      int op(int a, int b);
   }
 
   interface GreetingService {
      void sayMessage(String message);
   }
 
   interface SayHello {
      void sayHelloMethod();
 
   private int operate(int a, int b, Operation operation){
      return operation.op(a, b);
   }
}

The output of this should be :

10 + 5 = 15
10 - 5 = 5
10 x 5 = 50
10 / 5 = 2
Direct 10 + 5 = 15
Hello Mahesh
Hello Suresh
Hello

Now everything else is according to syntax ans fairly understandable. But what did we do at line 23? How did the compiler know that lambda expression is correct and it returns the correct value? How does the compiler know that the parameter list is OK?

We know that the operate() method needs parameters int, int, and Operation is that sequence. First two parameters passed are fine, but third parameter passed is a lambda expression. The java compiler is smart. It knows that an instance of Operation interface is needed. So the compiler matches the lambda expression to that interface. And that is why lambda expressions are used only for functional interface (interfaces with only one abstract method). As there is only one abstract method, the compiler matches the parameter list and the return value to that abstract method’s definition and gives errors if something is wrong. In our case, nothing is wrong so it compiles fine and outputs Direct 10 + 5 = 15.

That’s basically all about syntax of lambda expressions. We note that Java remains strongly and statically typed language. Even the lambda expression has a Type. Also, the compiler is able to infer the type of parameters based on the type of interface and hence we are not forced to mention to explicitly tell the type of parameters.

So we come to know that

  1. Lambda expressions are used primarily to define inline implementation of a functional interface, i.e., an interface with a single method only.
  2. Lambda expression eliminates the need of anonymous class and gives a very simple yet powerful functional programming capability to Java.

That’s it for this one. You can share your doubts in the comments section below.

Follow, comment, share.

Share this:
Share
«
»

Leave a Reply