Corporate Training
Request Demo
Click me
Menu
Let's Talk
Request Demo

Tutorials

Lambda Expressions and Functional Interfaces

19. Lambda Expressions and Functional Interfaces

Lambda expressions and functional interfaces are powerful features introduced in Java 8 that simplify the process of writing concise and expressive code for functional-style programming. In this Core Java tutorial, we'll explore lambda expressions and functional interfaces in detail, providing explanations and examples.

Lambda Expressions:

A lambda expression is a compact way to represent an anonymous function, i.e., a function without a name. Lambda expressions allow you to define and pass functions as arguments to methods, store them in variables, or return them as values. They are particularly useful for working with collections, streams, and for simplifying event handling.

Syntax of a Lambda Expression:
(parameters) -> expression or { statements }
 
  • 'parameters': The input parameters, which can be empty or multiple parameters separated by commas.
  • '->': The lambda operator that separates parameters from the body.
  • 'expression': A single expression that represents the operation to be performed. The result of this expression is the return value of the lambda.
  • '{ statements }': A block of statements enclosed in curly braces, similar to a method body. Use this when the lambda requires multiple statements or has no return value.

Examples of Lambda Expressions:

Lambda with No Parameters:
Runnable runnable = () -> {
    System.out.println("Hello, Lambda!");
};
 
Lambda with Parameters:
BinaryOperator add = (a, b) -> a + b;
 
Lambda with a Single Expression:
Consumer printMessage = message -> System.out.println(message);
 

Using Lambda Expressions:

Lambda expressions are commonly used with functional interfaces, which are interfaces with a single abstract method (SAM). Functional interfaces provide a clear contract for the lambda expression, specifying the input parameters and return type.

Functional Interfaces:

Functional interfaces provide the foundation for working with lambda expressions. They are also known as Single Abstract Method (SAM) interfaces because they have only one abstract method, which can be implemented using a lambda expression.

Common Functional Interfaces in Java:

  • 'Runnable': Represents a task that can be executed concurrently.
  • 'Callable': Represents a task that can be executed asynchronously and returns a result.
  • 'Supplier<T>': Represents a supplier of results, has no input arguments, and returns a value of type 'T' .
  • Consumer<T>': Represents an operation that takes a single input argument of type 'T' and returns no result.
  • 'Function<T, R>': Represents a function that takes an argument of type T and produces a result of type 'R'.
  • 'Predicate<T>': Represents a predicate (boolean-valued function) of one argument.

Examples of Functional Interfaces:

Using 'Runnable'
Runnable runnable = () -> {
    System.out.println("Hello, Runnable!");
};
 
Using 'Function'
Function square = x -> x * x;
int result = square.apply(5); // result is 25
 
Using 'Predicate'
Predicate isEven = x -> x % 2 == 0;
boolean even = isEven.test(6); // even is true
 

Using Functional Interfaces with Collections:

Functional interfaces are often used with Java collections and streams to perform operations like filtering, mapping, and reducing.

Using 'Predicate' to Filter a List
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
List evenNumbers = numbers.stream()
                                    .filter(x -> x % 2 == 0)
                                    .collect(Collectors.toList());
 
Using 'Function' to Map a List
List names = Arrays.asList("Alice", "Bob", "Charlie");
List nameLengths = names.stream()
                                .map(name -> name.length())
                                .collect(Collectors.toList());
 

Conclusion:

Lambda expressions and functional interfaces have transformed the way Java developers write code, making it more concise and expressive. They are particularly useful when working with collections, streams, and for simplifying event handling. Understanding how to use lambda expressions with functional interfaces and integrating them into your Java code is essential for writing clean and efficient code in modern Java development.