Lambda Expressions in Java Explained Clearly (With Practical Examples)

Lambda Expressions in Java

If you’ve been working with Java for a while, you know how verbose things can get — especially when using anonymous classes. But with Java 8, things got way better thanks to Lambda Expressions.

In this article, I’ll break down what lambda expressions are, why we use them, and how you can use them in your real-world Java code. This guide is for both beginners and intermediate Java devs who want to write cleaner and more modern code.


🔍 What Is a Lambda Expression in Java?

Simply put, a lambda expression is a short way of writing an anonymous function — a function without a name that can be passed around just like a variable.

Basic Syntax:

(parameters) -> { body }

And if there’s only one parameter and one line in the body, you can skip the brackets and even the data type:

name -> System.out.println("Hello, " + name);

✅ Why Do We Use Lambda Expressions?

Before lambda expressions, we had to use anonymous classes. That made the code lengthy and harder to read. With lambda, you get:

  • Shorter and cleaner code
  • Easier-to-read logic
  • Perfect combo with Java Streams and Collections
  • Better use of functional programming style

🎯 Functional Interface – The Core of Lambda

A lambda expression in Java must target a functional interface — which is just an interface with only one abstract method.

Example:

@FunctionalInterface
interface Calculator {
    int operate(int a, int b);
}

Java already has built-in ones like:

  • Runnable
  • Comparator<T>
  • Predicate<T>
  • Consumer<T>

🛠️ Simple Lambda Examples

1. Runnable Example (Old vs New)

Without Lambda:

Runnable r = new Runnable() {
    public void run() {
        System.out.println("Running...");
    }
};

With Lambda:

Runnable r = () -> System.out.println("Running...");

Much cleaner, right?


2. Custom Interface with Lambda

Let’s say you have this:

@FunctionalInterface
interface Greeting {
    void sayHello(String name);
}

Now use it like this:

Greeting greet = name -> System.out.println("Hello, " + name);
greet.sayHello("Makemychance Dev");

3. ForEach with Lambda (Collections)

List<String> names = Arrays.asList("John", "Jane", "Jack");

names.forEach(name -> System.out.println(name));

Or even shorter:

names.forEach(System.out::println);

💡 Lambda + Stream = Powerful Combo

One of the best use-cases is when working with Java Streams:

List<String> names = Arrays.asList("Ankit", "Aman", "Bobby");

List<String> filtered = names.stream()
    .filter(n -> n.startsWith("A"))
    .collect(Collectors.toList());

System.out.println(filtered); // [Ankit, Aman]

This makes filtering, mapping, sorting etc. so easy!


⚠️ Important Things to Remember

  • Lambda can only be used with functional interfaces.
  • You can’t modify variables from outside the lambda unless they are effectively final.
  • Don’t overuse lambdas — if logic is complex, a normal method might be better.

🔚 Final Words

Lambda expressions are a great addition to Java. They:

  • Help reduce code
  • Improve readability
  • Work beautifully with Collections and Streams

So if you’re still using old anonymous classes everywhere, it’s time to upgrade your code style!


📎 Useful Resources


🔗 Also Read:
👉 Asynchronous JavaScript: Promises, Async/Await, and Callbacks