Lambda expression in Java 8

  • Last Updated: July 30, 2023
  • By: javahandson
  • Series
img

Lambda expression in Java 8

In this article, we will learn what is a lambda expression in java 8. We will also learn how to make use of lambda expressions with proper examples.

 

A lambda expression is a form of method. Lambda expression takes in parameters, executes the logic, and returns a value. A lambda expression is a method without a name.

Syntax

(parameters) -> expression

Only single statement so curly braces are not required
(parameters) -> { statements }

We have to use curly braces with multiple statements

Before going in-depth about lambda expression we will learn what is a functional interface because only by using a functional interface we can create a lambda expression.

Functional interface

The functional interface is an interface with only one abstract method. An abstract method will have a declaration but no definition.

package com.javahandson;
public interface CalculateInterface {
     int calculate(int operand1, int operand2);
}

If we place more than one abstract method in an interface then it will not be treated as a functional interface.

Some predefined functional interfaces in Java APIs are Comparator, Runnable etc.

We can make use of @FunctionalInterface annotation to mark the interface as functional interface.

package com.javahandson;
@FunctionalInterface
public interface CalculateInterface {
     int calculate(int operand1, int operand2);
}

If we mark the interface with @FunctionalInterface and we add more than one abstract method to that interface then we will get a compile time exception.

package com.javahandson;
@FunctionalInterface
public interface CalculateInterface {
	int calculate(int operand1, int operand2);
	int sum(int operand1, int operand2);
}

Output : Invalid '@FunctionalInterface' annotation; CalculateInterface is not a functional interface

Creating lambda using a functional interface

Below is the functional interface

package com.javahandson;
@FunctionalInterface
public interface CalculateInterface {
	int calculate(int operand1, int operand2);
}

We will implement this interface using lambda expression as below

package com.javahandson;
public class Test {
  public static void main(String[] args) {
    CalculateInterface addition = (int operand1, int operand2) -> operand1 + operand2;
    int result = addition.calculate(10, 20);
    System.out.println("Addition is : " + result);
  }
}
Output: Addition is: 30

(int operand1, int operand2) -> operand1 + operand2

Here we have created a lambda expression which is an implementation of the calculate method. calculate method takes 2 arguments and returns an integer.

The way from anonymous function to lambda expression

Say we are implementing the CalculateInterface using an anonymous function, then it will look something like the below

package com.javahandson;
public class Test {
  public static void main(String[] args) {
    CalculateInterface calculateInterface = new CalculateInterface() {
      @Override
      public int calculate(int operand1, int operand2) {
        return operand1 + operand2;
      }
    };

    int result = calculateInterface.calculate(10, 20);
    System.out.println("Addition is : " + result);
  }
}

In the above code, there is a lot of boilerplate code that is not at all required.

We know CalculateInterface is a functional interface and it will have only one method, so naming that method is not at all required also writing the new operator doesn’t bring any value hence we will remove that as well. So after removing these 2 things, we are left with

CalculateInterface calculateInterface = (int operand1, int operand2) {
  return operand1 + operand2;
}

As part of lambda expression syntax, we should have a -> symbol between the parameters and expression hence

CalculateInterface calculateInterface = (int operand1, int operand2) -> { return (operand1 + operand2); };

Multiple abstract methods in a functional interface

At the top we have seen if we are adding multiple abstract methods in a functional interface then we get a compile-time exception saying

Invalid ‘@FunctionalInterface’ annotation; CalculateInterface is not a functional interface

Why is it so?

The main purpose of a functional interface is to create lambdas. Take a scenario and say multiple abstract methods are allowed in a functional interface. Now whenever we try to create a lambda expression with that interface then the compiler gets confused. The compiler will not understand we are providing an implementation for which abstract method and the ambiguity issue arises. Let us check the example below

package com.javahandson;

//Here we cannot use @FunctionalInterface annotation as we are using multiple abstract methods
public interface CalculateInterface {
  int calculate(int operand1, int operand2);
  int addition(int operand1, int operand2);
}
package com.javahandson;
public class Test {
  public static void main(String[] args) {
    CalculateInterface calculateInterface = (int operand1, int operand2) -> operand1 + operand2;
  }
}
Output: Output : Exception in thread "main" java.lang.Error: Unresolved compilation problem: The target type of this expression must be a functional interface

In the above example, we have the calculate method and addition method but while creating lambda, the compiler does not recognize the implementation we provided is for which abstract method hence we can see the compilation issue.

Hence we should use only one abstract method in a functional interface. If we are having only one abstract method in an interface then we can mark it with @FunctionalInterface annotation but this is optional.

Note* It is always better to mark the functional interface with @FunctionalInterface because we will get a compile time exception as soon as we try to add any new method to that functional interface.

So this is about lambda expressions in Java 8. I hope you like the article. If you are having any questions on this topic please raise them in the comments section.

Leave a Comment