March 8, 2016

Java 8: Understanding the Lambda Expression

As we know, the Java community is continuously contributing towards improving the Java language in terms of easy development, performance, and security, among other things. The introduction of JDK 8 is another step into this process. JDK 8 introduces many exciting new features that we’ve been waiting for, including Lambda Expression, which is one of the main features introduced.

Do you continue to have problems with the anonymous class? In day-to-day development, wherever it is required to impose a certain functionality to a functional interface without creating a separate sub-class, the anonymous class is always preferred.

Despite the fact that it’s simpler and faster to implement, its syntax makes it complex to understand and adopt, therefore it decreases the readability and understandability of code. Here is an Anonymous Class Example:

Obj.addXXXListener(new XXXListener() { 
  public void XXXPerformed(XXXEvent e)
 {
    // do something.
  } 
});

Introduction of Lambda Expression

There are many functional programming languages, such as Python and Lisp, that support Lambda Expression. These languages have the capability to define a function itself as an object without needing a class/object; this is in comparison to Java, which is a pure class-based, object-oriented programming language (except primitive data types) and has everything wrapped into class or object. Other functional languages like JavaScript don’t have such limitations; instead, we can create a function as a separate entity and assign it some variable to make it further usable.

Here is an example of a function as a separate entity and its assignment:

Var printFunObj = function print(element) {
    document.write(element, '
');
}

We can use the defined variable wherever we want to make a call to print function, such as:

     [1, 2, 3, 4, 5].forEach(Print);

Prior to JDK 8, it was not possible to define an inline method and reference its definition as an object. JDK 8 has introduced the ‘Lambda Expression’ to provide the capability of defining a function as a separate entity belonging to any class. This is the first step of Java moving toward becoming a functional programming language. By using the Lambda Expression, we can write the inline function without creating its interface’s subclass and can reference it as a variable. Informally it is also known as closure. The most important features of Lambda Expression are as follows:

  • It is a way of defining an inline method without creating its interface’s subclass. In other words, unlike class-based, object-oriented languages, a method can exist without belonging to a class.
  • A method defined as Lambda Expression can be passed as a parameter to another method
  • It supports Type Interface
  • It is based on a functional interface, like the anonymous class
  • It eliminates the use of anonymous class and provides the capability to be a powerful functional programming language.

Here is an example of a Lambda Expression:

    MyFuntionalInterface funtionalInterface = (a1, a2) -> return a1 > a2;

boolean result = myComparator.myFuntion(2, 5);


Syntax of Lambda Expression

Lambda Expression has a very simple and precise syntax, and it provides the flexibility to specify the datatypes for function parameters and its return type: parameter -> expression body To understand the syntax, we can divide it into three parts:

  1. Parameters: These are function method parameters and should be matched with the signature of a function defined in a functional interface. Defining the Parameters’ datatype is optional but the number of parameters should match with the defined signatures in the interface.
  2. Expression Body: This is either a single statement or a collection of statements that represent the function definition. Defining the datatype for the return object is optional.
  3. -> : This represents the Lambda Expression operator.

Type Interface in Lambda Expression

As we know, Java is statically a type language. This is also true for JDK 8; however, since JDK 8 came about, the Java compiler has the capability of a type inference. Without introducing the new Complex type and continuing to support the existing API, the Java Compiler uses a functional interface to make a type inference for the Java language possible. A type inference is a technique where a compiler uses a method declaration signature to identify the datatype for each Lambda Expression. For each method invocation, it looks into corresponding declarations to get datatype information for each parameter, and then it returns the type and makes it applicable to properly make a method call.

Functional Interface

The functional interface is an interface with only a single abstract method. The functional interface is also known as the Single Abstract Method Interface (SAM). Prior to JDK 8, we have had to use many interfaces, like marker interface, that contain only a single abstract method. Now, JDK 8 has redefined or recreated the definition of functional interface to introduce the Lambda expression. It provides the support of the @function annotation to validate the interface as a functional interface at the compiled time. Given below is an example of an invalid functional interface, which would compile a time error.

    @FunctionalInterface
public interface SimpleFuncInterface {
  public void doWork();
  public String toString();
  public boolean equals(Object o);

Do you have experience working with the Lambda Expression in Java 8? Have questions about getting started? Let me know in the comments section below and I’ll do my best to respond ASAP.