Published: February 4, 2016
Introduction
Lambda expressions were introduced in Java 8 as a way to write more concise and readable code by treating functions as first-class objects. They provide a clear and functional approach to writing code, especially when working with collections and streams.
In this tutorial, we’ll guide you through writing your first lambda expression. We’ll also explore how lambda expressions work, their syntax, and some practical use cases.
What Is a Lambda Expression?
A lambda expression is essentially an anonymous function that can be passed around and executed. It consists of:
- Parameters – the input values.
- Arrow (->) – separates the parameters from the body.
- Body – the action or the expression to be executed.
Lambda Expression Syntax:
(parameters) -> expression
- Parameters: The input values to the lambda expression.
- Arrow: The
->
symbol separates the parameters from the body. - Expression: The operation to be performed.
Basic Example:
Let’s begin by implementing a simple lambda expression that prints a greeting message. We’ll pass a string parameter, and the lambda will print “Hello, [name].”
public class Main {
public static void main(String[] args) {
// Lambda expression that prints a greeting message
Greeting greeting = (name) -> System.out.println("Hello, " + name);
// Calling the lambda expression
greeting.greet("Alice");
}
}
@FunctionalInterface
interface Greeting {
void greet(String name);
}
In this example, the Greeting
interface is a functional interface that has one abstract method greet(String name)
. We use a lambda expression to provide an implementation for this method, and when we call greeting.greet("Alice")
, it outputs:
Hello, Alice
Understanding the Lambda Syntax:
Let’s break down the syntax of a lambda expression:
- Parameters: The lambda takes a parameter (e.g.,
String name
), which is the input to the lambda function. - Arrow (
->
): The->
separates the parameter from the expression. - Expression: The lambda expression has a body, which in this case is a single statement (
System.out.println("Hello, " + name);
). For simple expressions like this, the result is returned automatically.
Lambda Expression with Multiple Parameters
Lambda expressions can accept multiple parameters as well. Let’s modify the example to create a lambda expression that takes two parameters and prints their sum.
public class Main {
public static void main(String[] args) {
// Lambda expression that takes two integers and prints their sum
MathOperation add = (a, b) -> System.out.println("Sum: " + (a + b));
// Calling the lambda expression with two arguments
add.operation(5, 3); // Output: Sum: 8
}
}
@FunctionalInterface
interface MathOperation {
void operation(int a, int b);
}
In this example:
- The
MathOperation
interface has a single abstract methodoperation(int a, int b)
. - The lambda expression
(a, b) -> System.out.println("Sum: " + (a + b));
calculates the sum of two integers.
Lambda Expressions with Return Values
You can also use lambda expressions that return a value. Instead of just performing an action, you can use the return
keyword in the body.
public class Main {
public static void main(String[] args) {
// Lambda expression that adds two integers and returns the result
MathOperation add = (a, b) -> a + b;
// Calling the lambda expression and storing the result
int result = add.operation(5, 3);
System.out.println("Result: " + result); // Output: Result: 8
}
}
@FunctionalInterface
interface MathOperation {
int operation(int a, int b);
}
Here, the MathOperation
interface returns an integer value, and the lambda expression (a, b) -> a + b
returns the sum of two integers. The result is stored in the result
variable and printed.
Using Lambda Expressions with Collections
One of the most common uses of lambda expressions is with collections. Java 8 introduced the Streams API, which allows you to perform operations on collections in a declarative way. Lambda expressions are often used in conjunction with streams.
Let’s say we have a list of numbers and want to find the sum of all even numbers:
import java.util.*;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// Using lambda expression with stream to filter and sum even numbers
int sum = numbers.stream()
.filter(n -> n % 2 == 0) // filter even numbers
.mapToInt(Integer::intValue) // convert to int
.sum(); // sum the numbers
System.out.println("Sum of even numbers: " + sum); // Output: Sum of even numbers: 30
}
}
In this example:
numbers.stream()
converts the list into a stream..filter(n -> n % 2 == 0)
filters out the even numbers using the lambda expressionn -> n % 2 == 0
..mapToInt(Integer::intValue)
converts the filtered stream into a stream of integers..sum()
computes the sum of the remaining numbers.
This code outputs the sum of the even numbers from the list, which is 30
.
Method References: Simplifying Lambda Expressions
Lambda expressions can be simplified using method references. A method reference is a shorthand for calling a method using a lambda expression. It can be used to refer to methods in classes or instances of objects.
Here’s an example using method references:
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// Using lambda expression to print each name
names.forEach(name -> System.out.println(name));
// Simplifying with method reference
names.forEach(System.out::println); // Output: Alice, Bob, Charlie
}
}
The names.forEach(System.out::println)
is a method reference that calls the println
method of the System.out
object.
Summary
In this tutorial, we’ve explored how to write and use lambda expressions in Java. Lambda expressions offer a powerful way to write functional-style code and can be applied to various situations, especially when working with collections and streams.
Key takeaways:
- Lambda expressions allow you to write concise and functional code.
- Syntax:
(parameters) -> expression
. - Common use cases include working with collections, filtering data, and simplifying code.
- You can simplify lambdas further using method references.
In the next tutorial, we will dive deeper into how functional interfaces and lambda expressions interact with Java’s Streams API.