You are here
Home > java >

Lambda Expression In Java

Lambda Expression In JavaLambda Calculus is a big change in mathematical world which has been introduced in 1930. Because of benefits of Lambda Calculus slowly this concept started being used in the programming world. “LISP” is the first programming which used Lambda Expression. Simultaneously, some other languages are already using lambda expressions such as : C, C++, C# .Net, C Objective, Python, Ruby and obviously Java as well. However, our topic of discussion is ‘Lambda Expression in Java’.

Lambda Expression in Java is one of the crucial feature within the new features introduced in Java 8. Let’s start discussing ‘Lambda Expression in Java’ and related concepts step by step.

Why we use Lambda Expression in Java?

The primary Objective of introducing Lambda Expression is to promote the benefits of functional programming in Java. Needless to say, Java follows more Object oriented programming approach than the functional programming approach. Keep in mind that just an introduction of Lambda expressions & Functional Interfaces doesn’t make Java a fully functional programming language. Instead, introduction of Lambda Expression in Java 8 was to include some features of a functional programming like other languages.

What is a Lambda (λ) Expression?

Lambda Expression is an anonymous (nameless) function. In other words, the function which doesn’t have the name, return type and access modifiers. Lambda Expression is also known as anonymous functions or closures.

We use Lambda Expression in Java when we provide an implementation of Functional Interfaces which is also a new feature of Java 8. Lambda expression in Java can also be used in a method as an argument which is one of the important feature of functional programming as the primary focus of Java 8. It provides a clear and concise way to represent one method interface using an expression only. Also, it is very useful in collection & Streams API. It should not be an exaggeration to say that Lambda Expression in Java is the biggest feature of Java 8.

How to write Lambda Expressions?

Suppose we have a traditional method for adding two numbers & printing the result on the console as below:

private void add(int i, int j){
System.out.println(i+j);
}

Step#1 : first, remove the access modifier

      void add(int i, int j) { System.out.println(i+j); }

Step#2 : next remove the return type

     add(int i, int j) { System.out.println(i+j); }

Step#3 : then, remove the method name

     (int i, int j) { System.out.println(i+j); }

Step#4 : insert arrow sign (->) between remaining method declaration & body

     (int i, int j) ->{ System.out.println(i+j); }

Step#5 : If compiler is able to identify the type of parameters, remove them as well

     (i, j) ->{ System.out.println(i+j); }

Now our Expression simplifies to :

     (i, j) ->{ System.out.println(i+j); }                                                                                                                                                                     

As there is only one statement in the method body, we may remove parenthesis as well. Now our final method simplifies to :

     (i, j) -> System.out.println(i+j); 

Example 1: Given below is a method to print “Hello Java 8” on the console.

public void m1() { System.out.println(“Hello Java 8”); } 

                   ⇓
() -> { System.out.println(“Hello Java 8”); }

Example 2: Here is another program to multiply two numbers and return the result.

public int multiply(int a, int b) { return (a*b); } 
            ⇓
(int a, int b) -> return (a*b); 
       ⇓ 
(a, b) -> a*b;

If the type of the parameter can be decided by compiler automatically based on the context then we can remove parameter types also.  The above Lambda expression can be rewritten as

         (a, b) -> a*b;

Example 3: Suppose we have a String, we are doing modification on this string & getting String again after multiple operations. We will write a method as below:

public String m2(String str1) { return str2; } 
            ⇓
(String str1) -> return str2; 
       ⇓
(str1) -> str2;

Lambda Expression in Java vs a Method in Java 

However, we can observe the clear difference between a Lambda Expression & a method in java after going through the above title “How to write Lambda Expressions”. Moreover, we can even observe the below differences :

Method: A method has various parts such as :

1) Method name

2) Parameter list

3) Return type

4) Access/Non-access Modifiers

5) method body

6) exception handlers with throws keyword and also try, catch in a normal scenario.

Lambda Expression: A Lambda expression has only two parts :

1) Parameter List

2) Body

Note on Lambda Expression in Java

1) If only one method parameter is available and compiler can understand the type based on the context, then we can remove the type & parenthesis both. Suppose (String s) -> {System.out.println(s)}; can be simplified to s -> {System.out.println(s)};

(String s) -> {System.out.println(s)};
             
 s -> {System.out.println(s)};

2) Similar to method body lambda expression body can contain multiple statements. If more than one statements present then we have to enclose it within curly braces. If one statement present then curly braces are optional. As in example at point # 1 can again be simplified as

 s -> System.out.println(s);

3) If no parameters are available, then we can use empty parenthesis like :

 ( ) -> System.out.println("No parameter test");

4) We can call the Lambda expression just like a traditional method, but only with the help of functional interfaces. We have covered Functional Interfaces topic in detail in other section.

5) Equally important, if you are learning Lambda expressions for the first time, Keep below syntax in your mind :

Interface iObj  = (params) -> { method body };

Benefits of Using Lambda Expressions 

1) We can write more readable, maintainable & concise code using Lambda expression in Java.
2) Also, we can incorporate functional programming capabilities in java language with Lambda Expressions.
3) We can use Lambda expressions in place of Inner classes to reduce the complexity of code accordingly.
4) Even we can pass a lambda expression as an argument to a method.
5) Additionally, we can provide lambda expression in place of an object.

Lambda Expression with respect to Anonymous Inner classes

When we use Anonymous inner classes, there are possibilities that we can use Lambda Expressions in place of the Anonymous inner class. Also one point to keep in mind here is that, if anonymous inner class implements Functional Interface in that particular case only we can replace it with lambda expressions. Therefore, when we convert our code to lambda expression, we reduce the length of the code & remove the complexity easily. Accordingly, let’s look at the code below to understand this concept easily.

Example of a Thread class with Anonymous Inner class

public class ThreadTest {
   public static void main(String[] args) {
     Thread t = new Thread(new Runnable() {
        public void run() {
           for (int i = 0; i < 10; i++) {
             System.out.println("Child thread is running");
           }
        }
     });
     t.start();
     for (int i = 0; i < 10; i++) {
        System.out.println("Parent thread is running");
     }
   }
}

Converted Example using Lambda Expression

public class ThreadTest {
   public static void main(String[] args) {
       Thread t = new Thread(() -> {
       for (int i = 0; i < 10; i++) {
           System.out.println("Child thread is running");
       }
       });
       t.start();
       for (int i = 0; i < 10; i++) {
          System.out.println("Parent thread is running");
       }
   }
}

Further, if you observe the above code thoroughly, following conclusion can be drawn easily.

//Code without using Lambda Expressions
Thread t = new Thread(new Runnable() {
   public void run() {
     for (int i = 0; i < 10; i++) {
        System.out.println("Child thread is running");
     }
   }
}); 

                       

//Code after using Lambda expression
Thread t = new Thread(() -> {
   for (int i = 0; i < 10; i++) {
      System.out.println("Child thread is running");
   }
});

Variable’s Behavior Inside Lambda Expression

1) We can't declare instance variable inside a Lambda expression.
2) Of course, variables declared inside Lambda expressions will be treated as a local variable.
3) ''this" keyword within Lambda expressions represents current outer class Object reference i.e. the class reference in which the Lambda expression is declared.

FAQ

When should we use a Lambda Expression?

When we need to pass behavior as an argument to a method, particularly when working with collections, streams, or functional interfaces, we should use Lambda Expression. They make code simple, easy to understand and improve readability as well.

What are Method References, and How are they related to Lambdas?

Method references are a shorthand notation for invoking a method using a lambda expression. They allow us to reference a method directly by its name, such as Class::method, instead of providing a lambda that calls the method.

Where do we use Lambda Expressions frequently?

We use Lambda expressions frequently with Java collections and the Stream API to perform operations like filtering, mapping, and reducing elements in a more explanatory and short way.

Are Lambda Expressions limited to Functional Interfaces only?

Lambda expressions are most commonly used with functional interfaces. However, we can also apply them to any interface with a single abstract method, even if it’s not explicitly annotated as a functional interface. Hence, technically we can use Lambda expressions with Functional interfaces only.

Do we have any limitations or constraints when using Lambda Expressions?

Lambda expressions have some constraints, such as the requirement for effectively final variables when accessing local variables. Additionally, they cannot capture mutable state or modify variables from their enclosing scope.

Do Lambda Expressions impact performance in any way?

Lambda expressions are intended to have minimal performance impact. In many cases, the performance difference between using lambda expressions and traditional code is negligible. However, in critical performance-sensitive scenarios, developers need to assess and profile their code.

Further, if you want to learn more about Lambda Expression In Java, kindly visit the Oracle Documentation.

Leave a Reply


Top