Java 8 – Lambda expressions

Let us look at lambda expressions, which is one of the most important features introduced in java 8. Before we look at lambda expressions, let us first understand the functional interfaces and anonymous classes.

What is functional interface?

Functional interface means an interface that has exactly one abstract method. They have only one functionality to exhibit. They are also called as Single Abstract Method Interfaces (SAM Interfaces).
A new annotation that is named as @FunctionalInterface is introduced in java 8 to restrict an interface from having more than one abstract method.

The above code will not compile unless we remove the extra abstract method.

Please note that it is not mandatory to add this annotation to a functional interface, but a good practice to add an additional compiler level of checking. However, there can be default methods in functional interfaces .Default methods are the methods with body definition which are introduced in java 8.

Some of the existing functional interfaces are Runnable, Cloneable, Comparator.
For example, Runnable interface has only one abstract method – run. The below is the definition of Runnable interface.

Java 8 has added a lot of functional interfaces under the package java.util.function. Some of them are Consumer, BiConsumer, Predicate, Function, Supplier.

What are Anonymous classes?

Anonymous classes are inner classes without a name.You can declare and instantiate at the same time. These are typically used while overriding a method from the existing class or interface.
For example, we have one abstract method called printArea() in the interface, which is to be overridden in the class Square to give the area of the Square.

Rather than creating a subclass class to override the method in the interface Shape, we are just creating an anonymous class. If you are just wondering how we are able to instantiate an interface, No, We did not instantiate interface. A pseudo named class is instantiated by the compiler, which extends the existing interface and it is the reason this is called anonymous class.
Hence, we save redundant lines of code here and also able to pass the functionality as argument.
Most typical uses of anonymous class are in GUI applications , where we might need to add new behaviors to already existing Objects.

ActionListener interface using anonymous class:

Anonymous classes can contain fields, new methods, instance initializers and local classes. Also anonymous classes are able to access the members of its enclosing class.

Lambda expressions:

We know java is an object oriented language and even behaviors are perceived as behavior of certain objects. With the use of Lambda expressions, We will be able to focus on the functional programming ability in java without worrying about objects. With this functional programming ,we can pass only functionality as arguments rather than passing objects or references as parameter. In other words, code can be passed as data.

Lambda expressions are a means to replace clumsy looking anonymous classes and to implement functional interfaces in a more readable fashion.

Syntax of lambda expression:

([comma seperated argument-list]) -> {body}

a. We can omit the data types since the compiler is able to guess the type of parameters. When there is a single argument the parentheses can also be omitted.
b. The arrow token -> is the one that connects the argument and functionality. This is mandatory.
c. The body contains the list of statements and expressions. In case of single statement or expression, the curly braces can be omitted.

The given anonymous class can be written using lambda expression as

Target typing allows the compiler to infer the type of the argument list and we can also write the above expression without specifying the type as below.

Since the body of this expression contain only a single statement, we can remove the curly braces and parentheses around single argument too and write as below. Now it becomes more concise than previous expressions.

With lambda expression, the compiler does not create a pseudo class which it creates while we use anonymous classes.

The above example has a functional interface named as Shape which has only one abstract method called printArea().

With the use of lambda expression, we do not have to use the new operator and the complete method definition. Its just the implementation code directly passed as expression. Hence, there is no extra class and no extra object created here thus saving memory.
The lambda expression is passed as object. The target of the lamba expression is functional interface here. Hence, the type of the lambda expression is Functional interface.
Lambda expressions can be passed as arguments to methods and can be assigned to variables. They can be used with streams and forEach statements for better efficiency.

Lambda expressions vs Anonymous classes:

Anonymous classes creates an extra class while lambda expression is converted into a private method. Lambda expression uses invokedynamic byte code instruction from Java 7 to bind this method dynamically.This saves time and memory for us.
Anonymous classes can be used in case of having more than one abstract method, but lambda expressions are specifically used for functional interfaces.
Scope of lambda expressions: Variables defined in the lambda expressions are accessible only within lambda expressions.The variables inside lambda expression can either be final or effectively final (should have a value) . Lambda expressions can access variables declared in its enclosing class.
This keyword used in lambda expression refers to its enclosing class object. But, this keyword used in anonymous classes refers to it anonymous class object.

Example using lambda expressions:

Let us look into a shopping system. A Shop contains items where each item has a name, id, price and type. Let us see how we can apply lambda expression to sort items based on certain attributes. We need to apply a special discount which is to be applied based on type of each item. This is achieved using lambda expression and functional interface.

Summary:

Lambda expressions is a  must read topic in java 8 since it paves a way to explore java in the functional programming perspective. In this article, we have discussed why we need lambda expressions and how and where we can use them. With the help of this article, I hope that you will be able to write your own lambda expressions.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.