MA-JAVA0 · Module 21
Lambdas, anonymous classes, and functional interfaces
Topics: Functional interface · Lambda · Anonymous class · Comparator
Overview
Session 21 — Lambdas, anonymous classes, and functional interfaces
Java 8 added lambda expressions—compact syntax for a block of code passed where a functional interface (one abstract method) is expected. Older code used anonymous classes for the same job. This session ties lambdas to Comparator, Runnable, event-style callbacks, and the @FunctionalInterface safeguard.
Time: about 95 minutes.
Concepts
1. Functional interfaces
A functional interface has exactly one abstract method (default methods on interfaces do not count toward that limit). Annotate with @FunctionalInterface so accidental second abstract methods become compile errors.
@FunctionalInterface
public interface IntPredicate {
boolean test(int value);
}
2. Lambda syntax
Parameters, arrow, body:
IntPredicate positive = v -> v > 0;
Multi-statement bodies use braces and explicit return:
IntPredicate noisyPositive = v -> {
boolean ok = v > 0;
return ok;
};
Types are often inferred from the target interface.
3. Anonymous classes (pre-lambda style)
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("from anonymous");
}
};
Still useful when you need multiple methods (rare with interfaces) or heavy per-instance setup—otherwise prefer lambdas for readability.
4. Variable capture
Lambdas may read effectively final locals from the enclosing scope:
String prefix = "[job]";
Runnable r = () -> System.out.println(prefix + " start");
You cannot mutate prefix after capture—compiler enforces effectively final rules.
5. Method references (preview)
When a lambda only forwards to an existing method, String::length or Objects::nonNull shorthand may apply—same functional interface target, terser syntax.
6. Comparator composition
import java.util.Comparator;
Comparator<String> byLen = Comparator.comparing(String::length);
Comparator<String> byLenThenLex = byLen.thenComparing(Comparator.naturalOrder());
Readable sorting keys beat hand-written compareTo chains.
7. Pitfalls
- Passing a lambda where the target type is ambiguous—add explicit cast to the functional interface or assign to a typed variable.
- Heavy work inside lambdas passed to parallel streams—side effects and contention surprise beginners (defer parallel streams until advanced material).
- Using lambdas where a named private method reads clearer—brevity is not always clarity.
Examples
Example A — sort with lambda
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class SortDemo {
public static void main(String[] args) {
List<String> items = new ArrayList<>(List.of("delta", "alpha", "charlie"));
items.sort((a, b) -> Integer.compare(a.length(), b.length()));
System.out.println(items);
}
}
Better style replaces the lambda with Comparator.comparing(String::length) once you recognise the pattern.
Example B — anonymous FilenameFilter (classic API)
import java.io.File;
import java.io.FilenameFilter;
public class PickTxt {
public static String[] txtOnly(File dir) {
return dir.list(new FilenameFilter() {
@Override
public boolean accept(File d, String name) {
return name.endsWith(".txt");
}
});
}
}
Modern code might use Files.newDirectoryStream with lambdas, but the anonymous class shows the implements-on-the-fly shape clearly.
Example C — capture of an effectively final local
public class Greeter {
public static Runnable forUser(String name) {
String msg = "Hello, " + name; // effectively final
return () -> System.out.println(msg);
}
}
The lambda closes over msg; reassigning msg after initialization would be a compile error because the lambda needs a stable snapshot.
Practice check — lambdas and functional interfaces
Multiple-choice check from the Matheion app lesson. Pick an answer for each question, then submit.
1.A functional interface is…
2.Which is a lambda that returns whether `n` is positive?
3.An anonymous class can…
4.`Comparator<String>` is often implemented with a lambda because…
5.Lambdas can capture local variables only if those variables are…