Java 8 Lambda Expressions: A Beginner's Guide with Real Examples

Aman WalkeAman Walke
3 min read

Introduction

Java 8 introduced Lambda Expressions, bringing functional programming to the Java ecosystem. Lambdas make your code shorter, more readable and easier to maintain — especially when working with collections and functional interfaces.

If you’ve ever written a verbose anonymous class just to pass behaviour, you’re going to love this feature!

What is Lambda Expression?

It is a anonymous function — without a name and access modifiers. It is used to implement a functional interface (an interface with only one abstract method).

Functional Interface Example

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

Lambda Expression Syntax

(parameters) -> {body}
  • Parameters: Input parameters for the lambda expression

  • Arrow Token (→): Used to separate parameters from the body

  • Body: Code to be executed

Lambda Expression Syntax Variations

No Parameters

() -> System.out.println("Hello, World!")

One Parameter

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

Multiple Parameters

(a, b) -> a + b

With Block Body

(a, b) -> {
    int sum = a + b;
    return sum;
}

Why use Lambda Expression?

Before Java 8, you had to use anonymous inner class to pass behaviour. They were verbose and cluttered code.

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

With lambda expression, above code can be simplified to:

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

It’s shorter, cleaner, and easier to understand.

Functional Interfaces

Lambda expressions can be used only with functional interfaces. Java 8 has introduced several functional interfaces, here are some commonly used ones (from java.util.function package):

1. Predicate

Represents a boolean valued function with one argument. It has a method test(T t)

Predicate<Integer> isEven = number -> number % 2 == 0; 
System.out.println(isEven.test(5)); // Output: false

2. Consumer

Represents a operation that takes in single parameter and does not produce any result. It has a method accept(T t).

Consumer<String> print = message -> System.out.println(message);
print.accept("Hello, Consumer!");

3. Function

Represents a function that takes in one parameter and produces a result. It has a method apply(T t).

Function<String, Integer> stringLength = string -> string.length();
System.out.println(stringLength.apply("Hello")); // Output: 5

4. BiFunction

Represents a function that takes in two parameters and returns a result. It also has a method apply(T t)

BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
System.out.println(add.apply(1, 2)); // Output: 3

5. Supplier

Represents a supplier of data

Supplier<Double> randomValue = () -> Math.random();
System.out.println(randomValue.get());

Using Lambda with Real World examples

Sorting with comparator

Before:

Collections.sort(list, new Comparator<String>() {
    public int compare(String a, String b) {
        return a.compareTo(b);
    }
});

After:

Collections.sort(list, (a, b) -> a.compareTo(b));

Using Lambda with Streams

List<Integer> names = Arrays.asList(1, 2, 3, 4, 5);

names.stream()
    .filter(num-> num % 2 != 0)
    .forEach(System.out::println); // Output: 1 3 5

Method Reference

Method references are shorthand for lambda expressions that call a method.

Example:

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

Types:

  • Static: ClassName::staticMethod

  • Instance: object::instanceMethod

  • Constructor: ClassName::new

Custom Functional Interface Example

@FunctionalInterface
interface Greeting {
    void say(String message);
}

public class Demo {
    public static void main(String[] args) {
        Greeting g = msg -> System.out.println("Hello, " + msg);
        g.say("World");
    }
}

Common Mistakes to Avoid

  1. ❌ Using lambdas with non-functional interfaces.

  2. ❌ Overcomplicating logic inside a lambda—extract into a method.

  3. ❌ Ignoring readability—sometimes a regular method is clearer.

Conclusion

Lambda expressions are a powerful feature in Java 8 that open the door to functional programming, making code concise, clean, and flexible. When combined with streams and functional interfaces, they allow you to write elegant solutions for everyday programming problems.

Start small—rewrite your anonymous classes with lambdas and gradually explore more with streams!

0
Subscribe to my newsletter

Read articles from Aman Walke directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Aman Walke
Aman Walke

I'm a tech enthusiast who loves building backend systems that just work — clean, scalable, and efficient. I've worked with microservices, Spring Boot, Azure, and APIs, and I enjoy digging into root causes and making systems better. Whether it's writing clean code, reviewing it, or managing deployments with DevOps tools, I'm always up for the challenge. I like working in collaborative environments where I can learn, share, and grow alongside smart people.