Lambda expressions are a powerful feature introduced in Java 8 that allow you to write more concise and readable code. They provide a way to represent one method interface using an expression. This tutorial will guide you through the basics of lambda expressions, how they relate to functional interfaces, and how to pass lambdas as parameters.
Lambda expressions are particularly useful when working with collections and streams in Java. They enable you to write more expressive and functional-style code. Understanding lambda expressions is crucial for leveraging modern Java features effectively.
A lambda expression is a short block of code which takes in parameters and returns a value. In Java, lambda expressions are used to implement single-method interfaces (functional interfaces) in a concise way.
The general syntax of a lambda expression is:
1
or
1(parameters) -> { statements; }
->): Separates the parameters from the body of the lambda.Let's start with a simple example where we define a lambda expression to add two numbers. We'll use the IntBinaryOperator functional interface, which represents an operation accepting two operands of type int.
1import java.util.function.IntBinaryOperator;23public class SimpleLambda {4public static void main(String[] args) {5// Define a lambda expression for adding two numbers6IntBinaryOperator add = (a, b) -> a + b;78// Call the lambda and print the result9int result = add.applyAsInt(10, 20);10System.out.println("Result: " + result);11}12}
Result: 30
In this example:
(a, b) -> a + b that takes two integers and returns their sum.IntBinaryOperator variable named add.applyAsInt method on add with arguments 10 and 20, which executes the lambda expression and prints the result.A functional interface is an interface that has exactly one abstract method. Lambda expressions can be used to implement these interfaces concisely. Java provides several built-in functional interfaces in the java.util.function package, such as:
Predicate<T>: Represents a predicate (boolean-valued function) of one argument.Function<T, R>: Represents a function that accepts one argument and produces a result.Consumer<T>: Represents an operation that accepts a single input argument and returns no result.Supplier<T>: Represents a supplier of results.Let's use the Predicate functional interface to check if a number is even.
1import java.util.function.Predicate;23public class FunctionalInterfaces {4public static void main(String[] args) {5// Define a lambda expression for checking if a number is even6Predicate<Integer> isEven = n -> n % 2 == 0;78// Test the predicate with different numbers9System.out.println("Is 4 even? " + isEven.test(4));10System.out.println("Is 7 even? " + isEven.test(7));11}12}
Is 4 even? true Is 7 even? false
In this example:
n -> n % 2 == 0 that checks if a number is even.Predicate<Integer> variable named isEven.test method of isEven to check if numbers 4 and 7 are even.Lambdas can be passed as parameters to methods, allowing for more flexible and reusable code. This is particularly useful when working with collections and streams.
Let's create a method that takes a lambda expression as a parameter and uses it to filter a list of numbers.
1import java.util.Arrays;2import java.util.List;3import java.util.function.Predicate;45public class PassingLambdas {6public static void main(String[] args) {7List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);89// Define a lambda expression for checking if a number is even10Predicate<Integer> isEven = n -> n % 2 == 0;1112// Print even numbers using the lambda13printNumbers(numbers, isEven);14}1516public static void printNumbers(List<Integer> numbers, Predicate<Integer> condition) {17for (Integer number : numbers) {18if (condition.test(number)) {19System.out.println(number);20}21}22}23}
2 4 6
In this example:
n -> n % 2 == 0 that checks if a number is even.printNumbers method, which filters and prints numbers based on the provided condition.Let's create a practical example where we use lambdas to sort a list of strings by their length.
1import java.util.Arrays;2import java.util.List;3import java.util.function.Comparator;45public class PracticalExample {6public static void main(String[] args) {7List<String> words = Arrays.asList("apple", "banana", "pear", "grape");89// Define a lambda expression for comparing strings by length10Comparator<String> compareByLength = (s1, s2) -> Integer.compare(s1.length(), s2.length());1112// Sort the list using the lambda13words.sort(compareByLength);1415// Print the sorted list16System.out.println(words);17}18}
[pear, apple, grape, banana]
In this example:
(s1, s2) -> Integer.compare(s1.length(), s2.length()) that compares two strings by their length.| Concept | Description |
|---|---|
| Lambda Expression | A short block of code representing a single method interface. |
| Functional Interface | An interface with exactly one abstract method that can be implemented by a lambda. |
| Passing Lambdas | Using lambdas as parameters to methods for more flexible and reusable code. |
In the next section, we will explore Java keywords in detail. Understanding keywords is essential for writing effective and idiomatic Java code. Make sure you have a solid grasp of lambda expressions before moving on to learn about other important Java features.
This tutorial provides a comprehensive introduction to lambda expressions in Java, including functional interfaces and passing lambdas as parameters. By the end of this section, you should be able to write concise and expressive code using lambda expressions in your Java applications.