Lambda Expressions In Simple Terms
Tags: programming, java, beginners, lambda
Published: 2021-01-27 12:51:57

A lambda expression is a short block of code which takes in parameters and returns a value. The sample expression below has one parameter. The expression can also contain two or more parameters.

```
parameter -> expression
```

A lambda expression can also be seen as an anonymous function. A function that doesn’t have a name and doesn’t belong to any class. Lambda expressions are similar to methods, but they do not need a name and they can be implemented right in the body of a method.

```
(parameter1, parameter2) -> expression
```

The concept of lambda expression was first introduced in LISP programming language. Expressions are limited. They have to immediately return a value, and they cannot contain variables, assignments or statements such as `if` or `for`. In order to do more complex operations, a code block can be used with curly braces. 

```
(parameter_list) -> {function_body}
```

If the lambda expression needs to return a value, then the code block should have a return statement.

##Components Of Lambda Expression
Lambda Expressions usually contain these 3 components:
* **Argument-list**: This argument is usually a list. It can be empty or non-empty as well.

* **Arrow-token**: It is used to link arguments-list and body of expression.

* **Body**: It contains expressions and statements for lambda expression. The body can be a simple statement or can contain a block of code.

###Some Sample Implementations and Outputs
For the first example, We'd start with a list of numbers. We are going to do a couple of mathematical computations on the content of this list.

```
// A Java program to demonstrate simple lambda expressions 
import java.util.ArrayList;

public class Main {
  public static void main(String[] args) {
    // Creating an ArrayList with elements  
    // And add elements{7,4,2} to the list
    ArrayList<Integer> numbers = new ArrayList<Integer>();
    numbers.add(7);
    numbers.add(4);
    numbers.add(2);

    //Using Lambda to print out all elements
    numbers.forEach( n -> System.out.println(n));

    //Using Lambda to print out the double value of each element
    numbers.forEach( n -> System.out.println(n+n));

    //Using Lambda to print all even elements
    numbers.forEach( n -> {if (n%2 == 0) System.out.println(n);});
  }
}
```
In the Java class above we have three different Lambda Expressions. 
* The first expression iterates through a list and prints out each value on a new line. 
* The second one print out the value of each element plus itself.
* The third one prints out only the even numbers.
  
*Output 1*
```
7
4
2
```
*Output 2*
```
14
8
4
```
*Output 3*
```
4
2
```

####Lambda Expression in Functional Interfaces. 
For these next examples, We'd work with Functional Interfaces. 
A **functional interface** in Java is an interface that contains only a single abstract (unimplemented) method. A functional interface can also contain default and static methods which do have an implementation.

* Functional Interfaces with No Parameter
```
interface MyFunctionalInterface {

    //A method with no parameter
    public String sayHello();
}
public class ExampleOne {

   public static void main(String args[]) {
        // lambda expression
    	MyFunctionalInterface message = () -> {
    		return "Hello";
    	};
        System.out.println(message.sayHello());
    }
}

```
*Output*
```
Hello
```

* Functional Interfaces with One Parameter

```
interface MyFunctionalInterface {

    //A method with one parameter
    public String sayHelloName(String str);
}
public class ExampleTwo {

   public static void main(String args[]) {
        // lambda expression
    	MyFunctionalInterface message = (str) -> {
    		return "Hello " + str;
    	};
        System.out.println(message.sayHelloName("Joy"));
    }
}

```
*Output*
```
Hello Joy
```
* Functional Interfaces with multiple Parameters

```
interface MyFunctionalInterface {

    //A method with one parameter
    public String concatStrings(String str1, String str2);
}
public class ExampleThree {

   public static void main(String args[]) {
        // lambda expression
    	MyFunctionalInterface message = (str1, str2) -> {
    		return str1 + str2;
    	};
        System.out.println(message.concatStrings("Good ","Day"));
    }
}

```
*Output*
```
Good Day
```
####Lambda Expression in Hash Maps.
Lambda Expression can also be used in Hash Maps, to iterate or do computational alterations on the elements of a Map. Let's see this example below.
```
public class HashMapExample{
  public static void main(String[] args) {
    // Creating a HashMap and putting in elements
    Map<String, Integer> prices = new HashMap<>();
    prices.put("Apple", 50);
    prices.put("Orange", 20);
    prices.put("Banana", 10);
    prices.put("Grapes", 40);

    //Using Lambda to print out all elements, k=key,v=value
    prices.forEach((k,v)->System.out.println("Fruit: " + k + ", 
    Price: " + v));
  }
}
```
*Output*
```
Fruit: Apple, Price: 50
Fruit: Orange, Price: 20
Fruit: Banana, Price: 10
Fruit: Grapes, Price: 40
```
####Lambda Expression For Running Threads
You can use lambda expression to run threads. In the following example, we are implementing run method by using lambda expression.
```
public class ThreadExample{
  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();  
  }
}
```
*Output*
```
Thread1 is running...
Thread2 is running...
```
####Lambda Expression to Compare and Filter Collection list
Lambda Expression can also be used as a comparator and can also be used to filter through a 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 FilterListExample{
  public static void main(String[] args) {
        List<Product> list=new ArrayList<Product>();  
        list.add(new Product(1,"Volvo",19000f));  
        list.add(new Product(3,"Tesla",75000f));  
        list.add(new Product(2,"Toyota",38000f)); 

        // using lambda to filter data  
        Stream<Product> filtered_data = list.stream().filter(p -> 
        p.price > 3000);  
          
        // using lambda to iterate through collection  
        filtered_data.forEach(  
                product -> System.out.println(product.name+": 
        "+product.price)   
       );
  }
}
```
*Output*
```
Tesla: 75000.0
Toyota: 38000.0
```
###Some Points to note when using Lambda Expression
* The body of a lambda expression can contain zero, one or more statements.
* When there is a single statement curly brackets are not mandatory and the return type of the anonymous function is the same as that of the body expression.
* When there are more than one statements, then these must be enclosed in curly brackets (a code block) and the return type of the anonymous function is the same as the type of the value returned within the code block, or void if nothing is returned

###Why Use Lambda Expressions
Here are some benefits of using Lambda Expressions.
1. Fewer Lines of Code:
One of the benefits of using lambda expression is the reduced amount of code.

2. Sequential and Parallel Execution Support by passing behavior in methods:
With the introduction of Stream API in Java 8, functions can be passed to collection methods and now it is the responsibility of collection to process the elements either in a sequential or parallel manner.

3. Higher Efficiency (Utilizing Multicore CPU’s):
Using Stream API’s and lambda expression we can achieve higher efficiency (parallel execution) in case of bulk operations on collections. Also, the lambda expressions can help in achieving internal iteration of collections rather than external iteration as shown in the above example. As nowadays we have CPUs with multicores, we can take advantage of these multicore CPU’s by parallel processing of collections using lambda.

In Summary, Lambda Expressions are welcome additions to any code base and this article is just meant to show us pointers on how to use and apply them.