Lambda Expression

Lambda expressions were introduced in Java 8 as a way to add functional programming features into the language.

Syntax

The syntax of a lambda expression consists of:

  • A comma-separated list of parameters in parentheses
  • The arrow token (->)
  • A body, which can be a single expression or a statement block between curly braces { }.

lambda-expression

  • Lambda expressions are essentially anonymous functions (methods without a name) that implement a functional interface.
  • A functional interface is an interface with a single abstract method.

Example of a functional interface:

1
2
3
4
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

Comparing Anonymous Classes vs. Lambda Approaches

We are going to look at two examples of using traditional anonymous classes inside a method versus creating lambda expression.

Example 1: Simple Calculator

Traditional Approach with Anonymous Classes

Before Java 8, if we wanted to implement a functional interface (an interface with just one abstract method), we have to create an anonymous inner class. This traditional approach was verbose and required a lot of boilerplate code.

TraditionalCalculator.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
interface Calculator {
  int calculate(int a, int b);
}

public class TraditionalCalculator {
  public static void main(String[] args) {
    // Traditional anonymous class approach
    Calculator adder = new Calculator() {
      @Override
      public int calculate(int a, int b) {
        return a + b;
      }
    };

    System.out.println("Traditional anonymous result: " + adder.calculate(5, 3)); 
  }
}

Lambda Expression Approach

LambdaCalculator.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
interface Calculator {
  int calculate(int a, int b);
}

public class LambdaCalculator {
  public static void main(String[] args) {
    // Lambdas approach
    Calculator adder = (a,b) -> { return a + b; };
    System.out.println("Traditional anonymous result: " + adder.calculate(5, 3));
  }
}

Example 2: Creating Threads

Traditional Thread with Anonymous Class

TraditionalThread.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class TraditionalThread{

  public static void main(String[]args){
    Runnable runnable = new Runnable() {
      @Override
      public void run() {
        System.out.println("Hello from traditional Runnable as anonymous class!");
      }
    };
    Thread thread = new Thread(runnable);
    thread.start();
  }
}

Thread with Lambda Expression

LambdaThread.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public class LambdaThread{

  public static void main(String[]args){
    Runnable runnable = () -> {
      System.out.println("Hello from traditional Runnable as anonymous class!");
    };
    Thread thread = new Thread(runnable);
    thread.start();
  }
}

Lambda Expression Body

Lambda expressions can have different forms of bodies with or without a return statement and curly braces.

1
2
3
4
5
6
7
8
// Single expression - no need for return or braces
Calculator add = (a, b) -> a + b;

// Block with multiple statements - requires braces and return statement
Calculator complexAdd = (a, b) -> {
    System.out.println("Adding " + a + " and " + b);
    return a + b;
};

Benefits of Lambda Expressions

  • Less code: More concise and clear code
  • Less repetition: Reduced boilerplate code (repetitive and often lengthy code).
  • Functional programming: Enhanced support for functional programming.