October 26, 2022

Java Lambda Expressions With Examples

Java Lambda expression is one of the most important addition in Java 8. It is a step towards functional programming in Java programming language. This Java Lambda expression tutorial gives an overview of lambda expressions like what are lambda expressions, how to write one and what are the advantages of using lambda expressions.

Functional interface in Java

Before delving deep into lambda expressions you should know about the functional interfaces in Java.

A functional interface is an interface with only a single abstract method (SAM). There are already many functional interfaces in Java  (though many new ones added in Java 8) like Runnable with its single run() method, Callable with its call() method or Comparator with its compare() method.

To know more about Functional interfaces in Java please refer this post- Functional Interface in Java

Lambda expression in Java

Java lambda expression is an implementation of a functional interface. It is an instance of a functional interface and the lambda expression you write implements the abstract method of the functional interface.

Let’s try to clarify it with an example. Generally when you implement a functional interface most probably you will implement it as an anonymous class. For example if you have to implement a Comparator you will write it as an anonymous class as given below-

List<Integer> myList = Arrays.asList(4, 7, 1, 10, 8, 12);
Collections.sort(myList, new Comparator<Integer>() {
  @Override
  public int compare(Integer o1, Integer o2) {		
    return o2.compareTo(o1);
  }
});

Since Comparator is a functional interface it can also be implemented as a Lambda expression.

Collections.sort(myList, (Integer o1, Integer o2)-> o2.compareTo(o1));

Some important points you should notice here are-

  1. By implementing a functional interface as a lambda expression, code is more compact.
  2. If you see the Collections.sort() method what you have done is written a function- (Integer o1, Integer o2)->o2.compareTo(o1) that represents an instance of a functional interface and it can be passed as a method argument. That is one of the advantages of lambda expression you can pass functionality as an argument to another method.

Arrow operator or Lambda operator

Java lambda expressions introduce a new operator -> knows as Arrow operator in Java. Arrow operator has two parts-

Left side specifies parameters required by the lambda expression which can be empty too if there are no parameters.

Right side is the lambda body which is actually the code of your lambda expression.

So the syntax of Java Lambda expression is as follows-

(type arg1, type arg2, ....) -> lambda body

Type can be inferred from the context in which lambda expression is used so you don’t need to explicitly specify type of the parameters.

(arg1, arg2, ....) -> lambda body

If we consider the lambda expression we have already written-

Lambda expressions in Java examples

Now when you have a good idea of functional interface and how to write a lambda expression let’s see some more examples of Lambda expressions in Java.

1- The simplest lambda expression is one with no parameters and just a return value and it can be written as.

()-> 10;
The above lambda expression is put to use in the following class.
// Functional interface
interface TestInterface{
  int getValue();
}

public class LambdaExample {
  public static void main(String[] args) {
    // assigning to functional interface reference
    TestInterface ref = () -> 10;
    System.out.println("Value- " + ref.getValue());
  }
}
Output
Value- 10

Some important points you should notice here are-

  • Since lambda expression is an instance of functional interface so it can be referred using a functional interface reference as done in this statement- TestInterface ref = () -> 10;
  • Since there are no parameters so left side of the arrow operator is just empty parenthesis.

2- A lambda expression with parameters.

// Functional interface
interface TestInterface{
  String getValue(String str1, String str2);
}

public class LambdaExample {
  public static void main(String[] args) {
    // assigning to functional interface reference
    TestInterface ref = (String str1, String str2) -> str1 + " " + str2;
    System.out.println("Value- " + ref.getValue("Hello", "Lambda"));
  }
}
Output
Value- Hello Lambda

Here we have a lambda expression with two String parameters. You don’t need to specify types of the parameters as that can be inferred from the context it is used, so this is also acceptable-

TestInterface ref = (str1, str2) -> str1 + " " + str2;

Lambda expression as a method argument

In the beginning we have already seen an example where Comparator implementation as a lambda expression is passed as a method argument. This is one of the feature of the lambda expression; to treat functionality as method argument.

If you have a method where argument is a functional interface then you can pass a lambda expression compatible with that functional interface as a method parameter.

In the following Java lambda expression as method argument example there is a method invoke that has a Callable as argument. Since Callable is a functional interface so a lambda expression compatible to it is passed as a parameter while calling invoke method.

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class LambdaExample {
  public static void main(String[] args) {
    LambdaExample obj = new LambdaExample();
    try {
      Future<String> f  = obj.invoke(()->"Calling callable");
      System.out.println("Value returned from callable- " + f.get());
    }catch(Exception e) {
      System.out.println("Exception message- " + e.getMessage());
    }      
  }
    
  //Method with Callable(funtional interface) as parameter
  <T> Future<T> invoke(Callable<T> c) throws Exception {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future<T> f =  executor.submit(c);
    executor.shutdown();
    return f;
  }
}
Output
Value returned from callable- Calling callable

Block lambda expressions in Java

What we have seen till now are all single expressions but you can also have lambda expressions having multiple statements known as block lambda expressions.

In a block lambda expression enclose the block of code with in curly braces and explicitly use return to return a value.

//Functional interface
interface TestInterface{
  String getValue(int i);
}

public class LambdaExample {
  public static void main(String[] args) {
    //block lambda
    TestInterface ref = (int i) -> {
      String s;
      if((i % 2) == 0) {
        s = "Even";
      }else {
        s = "Odd";
      }
      return s;
    };
    
    int num = 5;
    System.out.println(num + " is- " + ref.getValue(num));
  }
}
Output
5 is- Odd

That's all for the topic Java Lambda Expressions With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment