Lambda expressions in Java provide a clear and concise way to implement functional interfaces—interfaces with just a single abstract method. Introduced in Java 8, lambda expressions streamline the writing of anonymous classes and are especially useful in functional programming concepts like map-reduce transformations on collections.
Syntax of Lambda Expressions
The basic syntax of a lambda expression is:
1 |
(parameters) -> { expression; } |
or for single-expression lambdas:
1 |
(parameters) -> expression |
Example 1: Using Lambda with Runnable
Without lambda:
1 2 3 4 5 6 7 |
Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Runnable without lambda"); } }; new Thread(r1).start(); |
With lambda:
1 2 3 |
Runnable r2 = () -> System.out.println("Runnable with lambda"); new Thread(r2).start(); // Expected Output: Runnable with lambda |
Example 2: Iterating Over a List
Using lambda expressions with the forEach
method in List
.
1 2 3 4 5 6 7 8 9 |
import java.util.Arrays; import java.util.List; List<String> fruits = Arrays.asList("apple", "banana", "cherry"); fruits.forEach((fruit) -> System.out.println(fruit)); // Expected Output: // apple // banana // cherry |
Example 3: Using Lambda with Comparator
Sorting a list of custom objects by a property.
Given a class Person
:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Person { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } // Getters public String getName() { return name; } public int getAge() { return age; } } |
Sorting by age:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import java.util.ArrayList; import java.util.Collections; import java.util.List; List<Person> people = new ArrayList<>(); people.add(new Person("John", 25)); people.add(new Person("Amy", 22)); people.add(new Person("Steve", 29)); Collections.sort(people, (Person p1, Person p2) -> p1.getAge() - p2.getAge()); people.forEach((person) -> System.out.println(person.getName() + " is " + person.getAge() + " years old.")); // Expected Output: // Amy is 22 years old. // John is 25 years old. // Steve is 29 years old. |
Example 4: Using Lambda with Stream
API
Filtering and mapping with Streams:
1 2 3 4 5 6 7 8 9 |
List<Person> people = Arrays.asList(new Person("John", 25), new Person("Amy", 22), new Person("Steve", 29)); people.stream() .filter(p -> p.getAge() > 23) .map(Person::getName) .forEach(System.out::println); // Expected Output: // John // Steve |
This filters the people
list to only those older than 23 and then maps to their names, printing each name.
Example 5: Using Lambda to Implement Functional Interfaces
Using a custom functional interface:
1 2 3 4 5 6 7 8 9 10 11 12 |
@FunctionalInterface interface StringOperation { String operate(String str); } public class LambdaExample { public static void main(String[] args) { StringOperation toUpperCase = (str) -> str.toUpperCase(); System.out.println(toUpperCase.operate("hello")); // Expected Output: HELLO } } |
These examples with lambda expressions in Java demonstrate their utility in creating more readable and concise code, especially when working with collections, threads, and implementing functional interfaces. The expected outputs are included as comments to help verify the results of each code snippet when executed.
Conclusion
Lambda expressions in Java enhance the expressiveness and conciseness of your code, making it easier to work with functionalities that can be represented as single-method interfaces. They are particularly powerful in combination with the Stream API for processing collections and can significantly reduce the verbosity of your Java code.