Lambda Expressions
TL;DR
- Lambda Expressions (introduced in Java 8) provide a concise way to represent anonymous functions.
- They allow you to treat functionality as a method argument, or code as data.
- Basic Syntax:
(parameters) -> expressionor(parameters) -> { statements; } - They can only be used with Functional Interfaces.
Concept
Before Java 8, if you wanted to pass behavior to a method (like passing a sorting algorithm to Collections.sort), you had to create an Anonymous Inner Class. This resulted in bulky, verbose “boilerplate” code.
A lambda expression eliminates this boilerplate. It is essentially a block of code (an anonymous method) that gets passed around.
Behind the scenes, the Java compiler automatically converts the lambda expression into an instance of a Functional Interface (an interface with exactly one abstract method).
Examples
import java.util.ArrayList;
import java.util.List;
public class LambdaExample {
public static void main(String[] args) {
List<String> names = new ArrayList<>(List.of("Zach", "Alice", "Bob"));
// --- PRE-JAVA 8 (Anonymous Inner Class) ---
/*
names.sort(new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
*/
// --- JAVA 8 LAMBDA EXPRESSION ---
// (s1, s2) are parameters. The arrow -> points to the logic.
names.sort((s1, s2) -> s1.compareTo(s2));
System.out.println(names); // [Alice, Bob, Zach]
// Thread example using Runnable (which has a single run() method)
new Thread(() -> System.out.println("Running in a new thread!")).start();
}
}
Interview Questions
Q: Do you need to specify the parameter types in a lambda expression?
A: Usually, no. Java relies on Target Type Inference. Because Collections.sort() expects a Comparator<String>, the compiler automatically infers that s1 and s2 in (s1, s2) -> ... must be Strings. However, you can explicitly state them if desired: (String s1, String s2) -> ....
Q: Can a lambda expression access variables outside its scope?
A: Yes, a lambda can capture variables from its enclosing scope. However, those variables must be effectively final. This means that once the variable is initialized in the outer scope, its value cannot be changed anywhere in the code. If you try to modify an outer variable inside or outside the lambda, the compiler will throw an error.