Chapter 20: Lambda Expressions & Functional Interfaces (Java 8+)

one of the most loved and most used features in modern Java. They make your code shorter, cleaner, more readable, and open the door to functional programming style — especially when working with Streams, Collections, GUIs, and asynchronous code.

Imagine we’re sitting together in a cozy Mumbai café — it’s evening, the rain has just started outside, and I’m going to explain lambdas like I’m teaching my younger brother who just discovered how much easier life becomes after lambdas.

We’ll go super slowly, with real-life analogies, complete runnable programs, step-by-step breakdowns, tables, common mistakes with fixes, and tons of examples you can copy-paste and run right now.

Let’s dive in!

1. What is a Lambda Expression? (The Big Idea)

A lambda expression is a short, anonymous function — a way to write a method without giving it a name and without declaring a whole class.

Before Java 8 (old verbose way):

Java

With Lambda (Java 8+) — clean & short:

Java

Real-life analogy: Think of a remote control:

  • Old way: You need a full instruction manual (anonymous class) to tell the TV “turn on”.
  • Lambda way: You just press one button (() -> turnOn()) — same result, much less code!

2. Lambda Syntax (All Possible Forms)

Basic structure:

Java

Variations:

Form Syntax Example When to Use
No parameters () -> System.out.println(“Hi”) Simple actions with no input
One parameter (no parentheses) name -> System.out.println(“Hello ” + name) Single argument — cleanest form
Multiple parameters (a, b) -> a + b Normal math/logic operations
With explicit types (int a, int b) -> a + b When compiler needs help (rare)
With body & return (a, b) -> { return a + b; } Multiple lines or complex logic
Single expression (implicit return) (a, b) -> a + b Short & sweet — most common

Example 1: All Forms in Action

Java

Output:

text

3. Functional Interfaces (The Heart of Lambdas)

A functional interface is an interface that has exactly one abstract method (can have default/static methods).

Java provides many built-in functional interfaces in java.util.function:

Interface Abstract Method Signature Purpose / Common Use Example Lambda
Predicate<T> boolean test(T t) Check a condition → true/false x -> x > 18
Consumer<T> void accept(T t) Perform action on object (no return) name -> System.out.println(name)
Function<T,R> R apply(T t) Transform input to output str -> str.toUpperCase()
Supplier<T> T get() Produce a value (no input) () -> “Hello ” + Math.random()
BiFunction<T,U,R> R apply(T t, U u) Take two inputs, produce one output (a,b) -> a + b

Example 2: Using Built-in Functional Interfaces

Java

4. Method References (Even Shorter Lambdas)

Method references are a shorthand for lambdas when you just want to call an existing method.

Syntax: ClassName::methodName or object::methodName

Type Syntax Example Equivalent Lambda
Static method Math::max (a,b) -> Math.max(a,b)
Instance method (object) str::toUpperCase () -> str.toUpperCase()
Instance method (class) String::toUpperCase str -> str.toUpperCase()
Constructor ArrayList::new () -> new ArrayList<>()

Example 3: Method References in Action

Java

5. Quick Recap Table (Your Cheat Sheet)

Concept Syntax / Example Purpose / Benefit
Lambda Expression (a, b) -> a + b Short anonymous function
Functional Interface Interface with exactly one abstract method Target type for lambdas
Built-in FI Predicate<T>, Consumer<T>, Function<T,R>, etc. Ready-to-use for common tasks
Method Reference Class::method or obj::method Even shorter lambdas
Bounded Wildcard <? extends Number> Safe reading from collections

6. Common Mistakes & Fixes

Mistake Problem Fix
Using lambda with non-functional interface Compile error Ensure interface has exactly one abstract method
Forgetting parentheses for no params -> System.out.println(“Hi”) → error Use () -> …
Mixing varargs with lambdas incorrectly Confusing syntax Use (String… names) -> …
Trying to modify external variables inside lambda Compile error (unless effectively final) Use final or effectively final variables
Using raw types with lambdas Lose type safety Always use generics: Predicate<String>

7. Homework for You (Practice to Master!)

  1. Basic: Create a Predicate<String> that checks if a string is longer than 5 characters. Test with test().
  2. Medium: Use Consumer<String> to print names in uppercase using method reference.
  3. Advanced: Create a generic method <T> void process(List<T> list, Consumer<T> action) and use it with lambda and method reference.
  4. Fun: Use Supplier<String> to generate random greetings.
  5. Challenge: Sort a list of strings by length using lambda in Collections.sort() or List.sort().

You’re doing amazing! Lambdas & functional interfaces are the foundation of modern Java (Streams, Optional, CompletableFuture, Spring Boot, etc.) — now you’re writing clean, modern, professional code.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *