Sorry, you need to enable JavaScript to visit this website.

Introduction to Lambda expression in Java

Introduction to Lambda expression in Java
February 08, 2018

Lambda expressions or Lambdas are, typically, a simpler way to pass function (behavior) as an argument to another method or constructor. It is also called Function Pointers or Function References.

Lambdas were introduced in Java 8, and it was the most advertised and awaited feature of the release. Many other programming languages such as Pascal, Smalltalk, and C# support Lambdas in some way or the other. In fact, some JVM-based functional languages like Scala also support Lambdas. It was, thus, expected that Java as a language should introduce Lambdas, and the feature finally became part of the language in Java 8 through JSR 335.

In fact, some JVM based functional languages like Scala also support Lambdas.

Anonymous Inner Classes and How They Fit into the Picture

You must be familiar with inner classes in Java. One of the most widely used inner class type is Anonymous Inner class where, as the name implies, the class is not given a name. It is known that a class name is needed to create instance of the class, so in case of Anonymous Inner class, the instance is created right where the class is defined. Therefore, there is only one instance and no other instance can be created as the class name does not exist to instantiate it anywhere else.

Anonymous Inner classes typically implement an interface and specify the behavior by implementing the methods of the interface. A typical example from Java Swing would be the ActionListener interface having only one method, i.e., actionPerformed.

Any such interface that has only one method to be implemented is called Functional Interface. Lambdas are, typically, a new way to implement functional interfaces, where the focus is just to define and pass on the behavior without the overheads of implementing and initializing an interface.

Let us understand this through an example:

Lambda expression
Figure 1- Anonymous Inner Class

Let me explain the example in brief:

Line 1 creates a simple clickable button.

Line 2 adds an action listener to the button. An action listener is basically an instance of any class that implements the ActionListener interface and defines the actionPerformed method of the interface. Lines 4-9 are the method definition.

So, the above code snippet (line 2 onward) does the following:

  • Creates a new (anonymous) class that implements ActionListener interface
  • Implements the method from the interface and defines the behavior
  • Creates an instance of this anonymous class and passes it to the addActionListener method

As you could guess, the intent is to call the code in actionPerformed method when the button is clicked. Lambdas are just that. They take out the unnecessary boilerplate code and leave just what is needed. Here is the same code written in Java 8 using Lambda expression:

Lambda expression
Figure 2- Lambda Expression

There are only six lines now. If the first line, which is common to both snippets, is left out, then we have more than 40 percent code reduction for the same functionality. In practice, though, the code would not be this small but still a fair amount of reduction in code size happens, thus resulting in lighter libraries or zip files.

This is what we see on the face of it. Soon, I will talk about how it works under the hood. For now, let us understand the code snippet with Lambda expression.

A careful observation of the code shows that:

  • There is no Anonymous Inner class
  • There is no instance creation through new operator
  • There is no method called actionPerformed
  • There is just the body and the parameter that the method body needs in order to work correctly
  • The parameter type is also not needed
Lambda expression
Figure 3- Comparison

In Figure 3, the code highlighted in grey was removed to fit a single method anonymous class into a Lambda expression. The arrow in green is what needs to be inserted to denote that the body thereafter should be passed in as a function parameter to the caller function, i.e., actionPerformed.

Reduced Memory Footprint, Less Processing Overhead

If we compile the first code that uses Anonymous Inner class, we will see that it generates a class file with $1 suffix to our main class name, i.e., TestLambda$1.class. So, there are two classes:

  • TestLambda.class
  • TestLambda$1.class

And the total memory on disk consumed on my Windows machine is 8,192 bytes.

When we used Java 8 Lambda expression to achieve the same functionality, it doesn’t mean that the compiler internally generates the anonymous class by itself. In my setup, there is only one class, i.e.

  • TestLambda.class

And the total memory consumed is 4,096 bytes.

In addition to the reduced memory footprint, Lambdas are also efficient as there is no object creation required to call the method. No object creation means no allocation of heap and no garbage collection later.

Syntax of a Lambda Expression

Let us understand the syntax of a Java 8 Lambda expression in detail. It will help in understanding other cases and Java 8 Lambda example. A Lambda expression is made up of:

  • The formal parameter list in parenthesis. The parameter type is optional as it can be inferred. In fact, one may even avoid the parenthesis if there is only one formal parameter. If there is no parameter or more than one parameter, then the parenthesis is mandatory.

    So in the Figure 2, Line 2 could have been written as:

    btn.addActionListener(e -> {

  • The arrow sign
  • The expression body. This may contain a single expression or multiple expressions enclosed within a pair of curly braces. If the expression has one statement only, then return keyword is optional. Java directly infers the appropriate return type. If the body has multiple statements, then it is compulsory to have a return statement.

Wrap Up

Hope the blog post gave you a basic idea about Lambdas, one of the most important additions in Java as a language. I will write about further usage of Lambdas along with filters, another important feature of Java.