λ Java Lambda Expressions and Functional Interfaces
Master Java lambda expressions and functional interfaces — syntax, method references, the java.util.function package (Function, Predicate, Consumer, Supplier) and closures. With examples.
Lambdas (Java 8) let you pass behavior as data — the foundation of functional-style Java and the Streams API.
📜 Syntax
(params) -> expression
(params) -> { statements; }
Runnable r = () -> System.out.println("run");
Comparator<String> byLen = (a, b) -> a.length() - b.length();A lambda is an instance of a functional interface — an interface with exactly one abstract method.
🧩 The java.util.function toolbox
Function<T,R>— takes T, returns R (apply)Predicate<T>— takes T, returns boolean (test)Consumer<T>— takes T, returns nothing (accept)Supplier<T>— takes nothing, returns T (get)BiFunction<T,U,R>,UnaryOperator<T>, etc.
🔗 Method references
Shorthand for lambdas that just call a method:
String::toUpperCase(instance method of type)System.out::println(instance method of object)Integer::parseInt(static method)ArrayList::new(constructor)
🎒 Closures
Lambdas capture effectively final local variables — referenced but not reassigned. They can read outer variables but not mutate them.
💻 Code Examples
Predicate filter
Predicate<Integer> isEven = n -> n % 2 == 0;
List<Integer> evens = new ArrayList<>();
for (int n : List.of(1,2,3,4)) if (isEven.test(n)) evens.add(n);
System.out.println(evens);Output:
[2, 4]
Sort with a lambda comparator
List<String> names = new ArrayList<>(List.of("bob","al","cara"));
names.sort((a, b) -> a.length() - b.length());
System.out.println(names);Output:
[al, bob, cara]
Method reference
List.of("a","b","c").forEach(System.out::println);Output:
a b c
⚠️ Common Mistakes
- Trying to mutate a captured local variable inside a lambda — it must be effectively final.
- Writing a verbose lambda when a method reference is clearer (s -> s.toUpperCase() vs String::toUpperCase).
- Implementing a lambda for an interface with more than one abstract method — only functional interfaces qualify.
- Forgetting the lambda's type is inferred from context — it needs a target functional interface.
🎯 Interview Questions
Real questions asked at top product and service-based companies.
Q1.What is a lambda expression?Beginner
A concise way to provide the implementation of a functional interface's single abstract method, written as (params) -> body. It lets you treat behavior as a value you can pass around.
Q2.What is a functional interface?Beginner
An interface with exactly one abstract method (e.g., Runnable, Comparator, Function). It can be the target type of a lambda or method reference. @FunctionalInterface enforces the single-method rule.
Q3.Name the core functional interfaces in java.util.function.Intermediate
Function<T,R> (apply), Predicate<T> (test), Consumer<T> (accept), Supplier<T> (get), plus BiFunction, UnaryOperator, BinaryOperator and primitive specializations like IntFunction.
Q4.What is a method reference?Intermediate
Shorthand for a lambda that only calls an existing method. Forms: Type::staticMethod, object::instanceMethod, Type::instanceMethod, and Type::new (constructor reference).
Q5.What does 'effectively final' mean for lambda capture?Advanced
A local variable a lambda captures must not be reassigned after initialization (even without the final keyword). This avoids data races and matches the value-capture semantics of closures in Java.
🧠 Quick Summary
- Lambdas implement a functional interface's single abstract method.
- java.util.function: Function, Predicate, Consumer, Supplier.
- Method references (Class::method) are concise lambda shorthand.
- Lambdas capture effectively-final locals (read, not reassign).
- Lambdas power the Streams API and functional-style Java.