Skip to main content

Lambda Expression in Java

How to use Lambda Expression in Java

In this article, we are going to learn how to use Lambda Expression in java. We will look at how lambda expressions make our code so much easy to write and understand.
Basically, Lambda expression makes our code more focused on what to do not how to do, it helps us to remove unnecessary code from the program.

What is Lambda Expression Java

A Lambda Expression can be considered as a brief description of a method without a name. A method in java has a name, parameters/arguments, return type, and body, similarly, a lambda expression in java also consists of the arguments, body, and return type but without the name.
Let's have a first look at lambda expression in java:
// First look of Lambda expression in java
(Book book) -> {
 return book.getTitle().contains("Java");
};
Now, let's have a look at equivalent method representation in java:
boolean check(Book book) {
 return book.getTitle().contains("Java");
};
Don't think about the syntax of lambda expression now, we will discuss this later, but, as we can see in the case of lambda expression we just need to write what we need to. Also, we don't need to provide a name for the lambda expression as compared to the method definition.

Functional Interface

Before we are going to see how lambda expression works, first we should understand what is a Functional Interface. A Functional Interface is an interface that contains only one method declaration. For example:
interface BookConstraint{
  boolean check(Book book);
}
Runnable, Comparator all are the functional interfaces.
Java 8 introduced lambda expression which needs a functional interface or In other words, a lambda expression can only be written for a functional interface. Prior to Java 8, a functional interface can be instantiated using an anonymous class or by subclasses. Hence, we can say lambda expression is equivalent to anonymous Class or it is the replacement of anonymous classes
BookConstraint constraintByLambdaExpression =  (Book book) -> {
 return book.getTitle().contains("Java");
};
A similar representation of lambda expression in terms of Anonymous Class. As we can see how much unnecessary code we need to write.
BookConstraint constraintByAnonymousClass = new BookConstraint() {
     @Override
     public boolean check(Book book) {
         return book.getTitle().contains("Java");
     }
 };
Above, we have seen a simple way to write lambda expressions. Now, let's look at to use it:
Book book = new Book("Learn Java");
boolean isJavaBook = constraintByLambdaExpression.check(book);
if(isJavaBook){
   System.out.println("This is a Java Book");
}

Syntax: Lambda Expression in Java

A lambda expression is consists of three parts: the arguments, an arrow sign (->) and the lambda body.
//Syntax of lambda expression in java
(arguments) -> { 
   lambda body i.e., One or more statements;
}
  • Arguments: They are the arguments of the lambda expression. It can be zero or more. The sequence and type of arguments must be matched with the one-and-only method declare in the Functional Interface.
  • Arrow(->): The arrow sign is used to separate the arguments from the lambda body.
  • Lambda Body: This is the body of the lambda. Basically, it becomes the method definition of the one and only functional interface's method.

Few Example of Lambda Expression Java

(String str) -> { 
   return str.toUpperCase();
}
(String str1, String str2) -> { 
   return str1.concat(str2);
}
(Book book) -> { 
   return book.getTitle().contains("Java");
}
() -> { 
   return new Book();
}
// Also, this lambda not returning anything i.e., it returns void
(Book book, String title) -> { 
   title = title.toUpperCase();
   book.setTitle(title);
}

Single Line: Lambda Expression in Java

A lambda expression can be written in a single line when there is only one statement in the lambda body like all the examples mentioned earlier in this post.
// Syntax of single statement lambda expression in java
(arguments) -> expression;
NOTE: When we are writing single line lambda expression curly braces '{', '}' and return keyword is not used.
For instance, what it will look like for our BookConstraint Interface mentioned earlier in this post.
BookConstraint constraint = (Book book) -> book.getTitle().contains("Java");
One more thing, we can remove the argument type mention in the lambda expression because java knows the lambda expression is being written for which Functional Interface. So, Java automatically detects the type of the arguments according to the sequence declared in the method of Functional Interface. So finally, the code will look like:
BookConstraint constraint = book -> book.getTitle().contains("Java");

Few More Example of Single Line Lambda Expression Java

(str1 ,str2) -> str1.concat(str2);
() -> new Book();

Behavior Parameterization using Lambda Expression in Java

Behavior Parameterization is a programming paradigm in which we pass the behavior of a program from outside to parameterize the behavior. Let see how:
Suppose you have a list of the book with you and you need to write two functionalities: one is for that which returns all the books which contains the java in the title and another is for which will return all book having the price under Rs. 500/-.
A simple approach is to write two methods:
List<Book> filterJavaBook(List<Book> books){
    List<Book> javaBooks = new ArrayList<>();
    for (Book book : books) {
       if(book.getTitle().contains("Java")) {
           javaBooks.add(book);
       }
    }
    return javaBooks;
}
    
List<Book> filterPriceUnder500Book(List<Book> books){
    List<Book> priceUnder500Books = new ArrayList<>();
    for (Book book : books) {
       if(book.getPrice() <= 500) {
          priceUnder500Books.add(book);
       }
    }
    return priceUnder500Books;
}
This approach is simple but what happens if we need to write 5 or 10 or more functionalities like this, then we need to write n number of methods that make our code very verbose and hard to maintain. To handle this situation we can parameterize the behavior. Let see how
For Behavior Parameterization, first, we need to create an interface that works as an abstraction for the behavior in the method. Let's re-use our BookConstraint interface.
interface BookConstraint{
  boolean check(Book book);
}
This interface works as the behavior of the functionality within the method and the behavior is provided from outside of the method as the argument either by the lambda expression or by the anonymous class.
List<Book> filterBooks(List<Book> books , BookConstraint bookConstraint){
    List<Book> filteredBooks = new ArrayList<>();
    for(Book book : books) {
        if(bookConstraint.check(book)) {
             filteredBooks.add(book);
        }
    }
    return filteredBooks;
}
Now we can create any number of behaviors for the method and pass the behavior as an argument. To write the definition of the behavior we can use either lambda expression or anonymous classes but we have seen above which one is better and easy to write.
List<Book> javaBooks = filterBooks(listOfAllBooks , book -> book.getTitle().contains("Java"));
List<Book> priceUnder500Books = filterBooks(listOfAllBooks, book -> book.getPrice() <= 500);

Conclusion

In this article, we have learned lambda expression in java, how and where to use that, how it is better than the anonymous class, and how it makes our code very neat and clean. Also, we learned how to use a lambda expression to achieve behavior parameterization.
Thanks for reading this article.
If, we missed something please let us know in the comment section below.
Happy Learning

Related Topics

Functional Interface in Java
Java Optional

Comments