Companies regularly need to update their applications for smooth functioning and implementation of new features. Developers continuously work on making the applications fast, smooth and secure. Modern applications use serverless and Cloud technologies For this, it is essential to have hands-on versatile programming languages such as Java. Java is a high-level programming language widely used in the majority of enterprise applications and backend services for running business activities.

In this article, you will gain information about Java Lambda Expressions. You will also gain a holistic understanding of Java, its key features, Java Lambda Expressions, its benefits, syntax, rules, examples, uses and limitations. Read along to find out in-depth information about Java Lambda Expressions.

What is Java?

Java Lambda: Java Logo

Java is a popular programming language that’s mostly used for server-side development as well as mobile app development. In its design, Java is an object-oriented language which simply means that all data and methods are represented as classes and objects.

Key Features of Java

The following features give Java an edge over other Programming Languages:

  • Object-Oriented: Java Programming Language treats everything as an object. It can easily map real-world scenarios into code by treating individual entities as objects. 
  • Platform Independent: Unlike programming languages ​​like C and C ++, Java is not compiled in a platform-specific machine. It produces a platform-independent Byte Code that is distributed over the internet and is interpreted by the Java Virtual Machine (JVM) installed on any system. 
  • Security: With the security feature of Java Programming Language, it allows you to develop tamper-proof and virus-free systems. Also, it uses Public-key cryptography-based authentication techniques to keep your code and data safe.
  • Portable: Java is an architecture-independent Programming Language. So it is easy to port a code written in Java Programming Language to different processors.
  • Robust: Java is a Programming Language that strives to eliminate error-prone instances using compile-time error checking and runtime checking.

What are Java Lambda Expressions?

A Java Lambda Expression is a short block of code that accepts parameters and returns a value. Java  Lambda expressions are similar to methods in that they do not require a name and can be implemented directly in the method body.

In simpler terms, a Lambda Expression is an unnamed anonymous function. This anonymous function is passed as an argument to another method or stored in a variable. In Java 8, Lambda Expressions were introduced.

It saves a significant amount of code. You don’t need to define the method again in the case of Lambda expression to provide the implementation. You simply write the implementation code here.As a Lambda expression in Java is treated as a function, the compiler does not generate a .class file.

The Lambda expression implements a functional interface. A functional interface is one that has only one abstract method. The annotation @FunctionalInterface in Java is used to declare an interface as a functional interface.

Syntax of Java Lambda Expressions

The syntax of Java Lambda Expression is as follows:

(a, b) -> {}

Lambda Expressions consist of three entities:

(int arg1, String arg2) -> {System.out.println("Two arguments"+arg1+"and"+arg2);}

where,

  • (int arg1, String arg2) is the Argument List
  • -> is the arrow token
  • {System.out.println(“Two arguments”+arg1+”and”+arg2);} is the body of the lambda expression

1) Argument List (a,b)

The argument list is a list of parameters separated by commas and enclosed in parentheses. These arguments typically do not require type declarations because the compiler can infer their types. If you only have one argument, the parentheses () are not required.

2) Arrow token ->

This is the syntax for lambda expressions and indicates that the parameters have been passed to the body.

3) Body {}

The body is a code block that represents how a functional interface is implemented. If the body contains only one statement, the expression will evaluate it and return the result. The brackets are optional in this case. If the body contains more than one statement, use brackets and return the result.

No Parameter Syntax

() -> {  
//Body of no parameter lambda  
}  

One Parameter Syntax

(p1) -> {  
//Body of single parameter lambda  
}  

Two Parameter Syntax

(p1,p2) -> {  
//Body of multiple parameter lambda  
}  

Rules of Java Lambda Expressions

The rules that Lambda Expressions must bind to are as follows:

  • Parameters are not mandatory. It can be 0 or greater.
 () -> {System.out.println("Hello World");};
 (int a) -> {System.out.println("value "+a);};
  • If no parameters are available, you must use an empty parenthesis ().
() -> {System.out.println("Hello World");};
  • If you have multiple parameters, use a comma to separate them (,)
(int a, int b) -> System.out.println("sum "+(a+b));
  • Curly braces are optional if the body contains only one statement.
 (int a) -> System.out.println("value "+a);
  • If the body contains more than one statement, curly braces are necessary.
() -> {
   System.out.println("Hello World");};
   System.out.println("value "+a);
    };
  • The type(s) of parameter(s) is/are optional. There is no need to declare manually because the compiler can anticipate based on the context.
(a) -> System.out.println("value "+a);
 (a, b) -> System.out.println("sum "+(a+b));
  • If only one parameter is available, parenthesis is not mandatory.
(int a) -> {System.out.println("value "+a);};

OR

a -> {System.out.println("value "+a);};
  • Functional Interface can be assigned a Java lambda expression.
SummatiobInterface sumInt = (int a, int b) -> a+b;

Examples of Java Lambda Expressions

Some of the examples of using Lambda Expressions are as follows:

1) Getting String length

(String str) -> str.length();

This takes a single string parameter. This method also returns an integer value. However, the returned type is not visible because it is not declared anywhere in the declaration. It is used internally and is based on the lambda body. If lambda only has one statement that returns a value, it becomes a return type.

2) Employee Rating Check

(Employee emp) -> emp.getGrade().equals("A");

It takes one parameter of the type “Employee” and returns a boolean value. Lambda Body checks for a “A” grade and returns true or false.

3) Concatenate two Strings and Print Output

(String str1, String str2) -> {
                                String output = str1.concat(str2);
          System.out.println("Concantenated string "+output);
         }

It accepts two String parameters and does not return anything. That implies that the return type is void. The body contains two statements that concatenate the output string and print it.

Uses of Java Lambda Expressions

The different uses and implementation of Java Lambda Expressions are as follows:

1) No Parameter

In this case, Lambda Expression doesn’t have any parameters.

interface Sayable{  
    public String say();  
}  
public class LambdaExpressionExample3{  
public static void main(String[] args) {  
    Sayable s=()->{  
        return "I have nothing to say.";  
    };  
    System.out.println(s.say());  
}  
}  

Output:

I have nothing to say.

2) Single Parameter

In this case, Lambda Expression has a single parameter.

interface Sayable{  
    public String say(String name);  
}  
  
public class LambdaExpressionExample4{  
    public static void main(String[] args) {  
      
        // Lambda expression with single parameter.  
        Sayable s1=(name)->{  
            return "Hello, "+name;  
        };  
        System.out.println(s1.say("Sonoo"));  
          
        // You can omit function parentheses    
        Sayable s2= name ->{  
            return "Hello, "+name;  
        };  
        System.out.println(s2.say("Sonoo"));  
    }  
}  

Output:

Hello, Vikash
Hello, Vikash

3) Multiple Parameters

In this case, Lambda Expression has multiple parameters.

interface Sayable{  
    public String say(String name);  
}  
  
interface Addable{  
    int add(int a,int b);  
}  
  
public class LambdaExpressionExample5{  
    public static void main(String[] args) {  
          
        // Multiple parameters in lambda expression  
        Addable ad1=(a,b)->(a+b);  
        System.out.println(ad1.add(10,20));  
          
        // Multiple parameters with data type in lambda expression  
        Addable ad2=(int a,int b)->(a+b);  
        System.out.println(ad2.add(100,200));  
    }  
}  

Output:

30
300

4) With or Without Return Keyword

In this case, Lambda Expression showcases the usage of both with and without return keywords.

If there is only one statement in a Lambda expression, you may or may not use the return keyword. When a lambda expression contains multiple statements, the return keyword must be used.

interface Addable{  
    int add(int a,int b);  
}  
  
public class LambdaExpressionExample6 {  
    public static void main(String[] args) {  
          
        // Lambda expression without return keyword.  
        Addable ad1=(a,b)->(a+b);  
        System.out.println(ad1.add(10,20));  
          
        // Lambda expression with return keyword.    
        Addable ad2=(int a,int b)->{  
                            return (a+b);   
                            };  
        System.out.println(ad2.add(100,200));  
    }  
} 

Output:

30
300

5) Foreach Loop

In this case, Lambda Expression showcases the usage of Foreach Loop.

import java.util.*;  
public class LambdaExpressionExample7{  
    public static void main(String[] args) {  
          
        List<String> list=new ArrayList<String>();  
        list.add("Arpit");  
        list.add("Aman");  
        list.add("Ankit");  
        list.add("Ajay");  
          
        list.forEach(  
            (n)->System.out.println(n)  
        );  
    }  
}  

Output:

Arpit
Aman
Ankit
Ajay

6) Multiple Statements

In this case, Lambda Expression showcases the usage of multiple statements.

@FunctionalInterface  
interface Sayable{  
    String say(String message);  
}  
  
public class LambdaExpressionExample8{  
    public static void main(String[] args) {  
      
        // You can pass multiple statements in lambda expression  
        Sayable person = (message)-> {  
            String str1 = "I would like to say, ";  
            String str2 = str1 + message;   
            return str2;  
        };  
            System.out.println(person.say("time is precious."));  
    }  
}  

Output:

I would like to say, time is precious.

7) Creating Thread

To run a thread, you can use a Lambda expression. The run method is implemented in the following example using a Lambda expression.

public class LambdaExpressionExample9{  
    public static void main(String[] args) {  
      
        //Thread Example without lambda  
        Runnable r1=new Runnable(){  
            public void run(){  
                System.out.println("Thread1 is running...");  
            }  
        };  
        Thread t1=new Thread(r1);  
        t1.start();  
        //Thread Example with lambda  
        Runnable r2=()->{  
                System.out.println("Thread2 is running...");  
        };  
        Thread t2=new Thread(r2);  
        t2.start();  
    }  
}  
import java.util.ArrayList;  
import java.util.Collections;  
import java.util.List;  
class Product{  
    int id;  
    String name;  
    float price;  
    public Product(int id, String name, float price) {  
        super();  
        this.id = id;  
        this.name = name;  
        this.price = price;  
    }  
}  
public class LambdaExpressionExample10{  
    public static void main(String[] args) {  
        List<Product> list=new ArrayList<Product>();  
          
        //Adding Products  
        list.add(new Product(1,"HP Laptop",25000f));  
        list.add(new Product(3,"Keyboard",300f));  
        list.add(new Product(2,"Dell Mouse",150f));  
          
        System.out.println("Sorting on the basis of name...");  
  
        // implementing lambda expression  
        Collections.sort(list,(p1,p2)->{  
        return p1.name.compareTo(p2.name);  
        });  
        for(Product p:list){  
            System.out.println(p.id+" "+p.name+" "+p.price);  
        }  
  
    }  
}  

Output:

Thread1 is running...
Thread2 is running...

8) Comparator

In this case, it showcases of usage of Lambda Expression in a Comparator.

import java.util.ArrayList;  
import java.util.List;  
import java.util.stream.Stream;   
class Product{  
    int id;  
    String name;  
    float price;  
    public Product(int id, String name, float price) {  
        super();  
        this.id = id;  
        this.name = name;  
        this.price = price;  
    }  
}  
public class LambdaExpressionExample11{  
    public static void main(String[] args) {  
        List<Product> list=new ArrayList<Product>();  
        list.add(new Product(1,"Samsung A5",17000f));  
        list.add(new Product(3,"Iphone 6S",65000f));  
        list.add(new Product(2,"Sony Xperia",25000f));  
        list.add(new Product(4,"Nokia Lumia",15000f));  
        list.add(new Product(5,"Redmi4 ",26000f));  
        list.add(new Product(6,"Lenevo Vibe",19000f));  
          
        // using lambda to filter data  
        Stream<Product> filtered_data = list.stream().filter(p -> p.price > 20000);  
          
        // using lambda to iterate through collection  
        filtered_data.forEach(  
                product -> System.out.println(product.name+": "+product.price)  
        );  
    }  
}  

Output:

Sorting on the basis of name...
2 Dell Mouse 150.0
1 HP Laptop 25000.0
3 Keyboard 300.0

9) Filter Collection Data

In this case, it showcases of usage of Lambda Expression in Filter Collection data.

Output:

Iphone 6S: 65000.0
Sony Xperia: 25000.0
Redmi4 : 26000.0

10) Event Listener

In this case, it showcases of usage of Lambda Expression in an Event Listener example.

import javax.swing.JButton;  
import javax.swing.JFrame;  
import javax.swing.JTextField;  
public class LambdaEventListenerExample {  
    public static void main(String[] args) {  
        JTextField tf=new JTextField();  
        tf.setBounds(50, 50,150,20);  
        JButton b=new JButton("click");  
        b.setBounds(80,100,70,30);  
          
        // lambda expression implementing here.  
        b.addActionListener(e-> {tf.setText("hello swing");});  
          
        JFrame f=new JFrame();  
        f.add(tf);f.add(b);  
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        f.setLayout(null);  
        f.setSize(300, 200);  
        f.setVisible(true);  
  
    }  
  
}  

Output:

Java Lambda: Output
Java Lambda: Output

Benefits of Java Lambda Expressions

The benefits of Lambda Expressions are as follows:

1) More Concise Syntax

Lambda expressions enable you to write fewer lines of code than an anonymous class to implement a functional interface.

A) Implementing the Print interface using a nested class:

interface  Print {
    void print(String message);
}

public class MainClass {
    public static void main(String args[]) {
        //using nested class
        Print myNestedPrinter = new Print(){
            public void print(String x) {
                System.out.println(x);
            }
        };
        //using lambda
        Print myPrinter = x -> System.out.println(x);

        myNestedPrinter.print("Hello nested classes");
        myPrinter.print("Hello lambdas!");
    }
}

B) Implementing the Print interface using Java Lambda Expression

interface  MathOp {
    int operate(int a, int b);
}

public class MainClass {
    public static void printResults(int x) {
        System.out.println(x);
    }

    public static void main(String args[]) {
        MathOp add = (a, b) -> {
            return a + b;
        };
        printResults(add.operate(2, 2));
        //prints 4
    }
}

The above example shows the advantage of using a Java lambda expression over an anonymous class. You must explicitly create a new instance of the Print interface and implement its print method when using the anonymous class. This requires four more lines of code than using a Lambda expression.

2) Easier to work with Collections

Lambdas provide a much more elegant way of working with collections. For example:

import java.util.*;
public class MainClass {
    public static void main(String args[]) {
        List<Character> list = new ArrayList<Character>();
        list.add('a');
        list.add('b');
        list.add('c');
        list.forEach(x -> System.out.println(x));
    }
}

A Lambda expression x -> System.out.println(x) that is applied to each element in the collection using the forEach method.

When used with the Streams API, this is considered an internal iteration and may have some performance implications. More specifically, parallel processing is simple to implement with internal iterations because they offload iteration management to a process. This is in contrast to external iterations, which completely control how the iteration is implemented.

Limitations of Java Lambda Expressions

In Java, Lambda expressions (and anonymous classes) can only access the final (or effectively final) variables of the enclosing scope.

For example:

void fn() {
    int myVar = 42;
    Supplier<Integer> lambdaFun = () -> myVar; // error
    myVar++;
    System.out.println(lambdaFun.get());
}

This does not compile because myVar‘s incrementation prevents it from being effectively final.

Learn More About:

Conclusion

In this article, you have learned about Java Lambda Expressions. This article also provided information on Java, its key features, Lambda Expressions, its benefits, syntax, rules, examples, uses and limitations.

Share your experience of understanding Java Lambda Expressions in the comment section below! We would love to hear your thoughts.

Veeresh Biradar
Senior Customer Experience Engineer

Veeresh is a skilled professional specializing in JDBC, REST API, Linux, and Shell Scripting. With a knack for resolving complex issues and implementing Python transformations, he plays a crucial role in enhancing Hevo's data integration solutions.