Skip to main content

Command Palette

Search for a command to run...

Modern Java Features: Lambdas & Streams

Updated
4 min readView as Markdown
Modern Java Features: Lambdas & Streams
M

I’m a backend software engineer with over a decade of experience primarily in Java. I started this blog to share what I’ve learned in a simplified, approachable way — and to add value for fellow developers. Though I’m an introvert, I’ve chosen to put myself out there to encourage more women to explore and thrive in tech. I believe that by sharing what we know, we learn twice as much — that’s precisely why I’m here.

Part 1: Understanding Lambdas for Beginners

🤔 What’s a Lambda?

A lambda expression is a short way to write anonymous functions (a function without a name):

📝 Basic Syntax

(parameters) -> { body }

Or shorter if it's one line:

(param) -> doSomething

Lambdas are meant to be simple and short, though you can define multi-line lambdas very often they are one-liners. When you use one-liner lambdas code tends to be more readable and cleaner. Check out this example:

✅ Example: Sorting with Lambdas

Before Lambdas:

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

With Lambdas:

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

So much cleaner!

Here’s another example:

List<String> names = List.of("Alice", "Bob", "Charlie");

names.stream()
     .filter(name -> name.startsWith("A"))
     .forEach(System.out::println);

name -> name.startsWith("A") is a lambda — a function that takes name and returns a boolean.

Lambdas in Java enable functional programming by allowing you to treat behavior as data — passing functions around just like variables or objects. This leads to more concise, expressive, and modular code, especially when working with streams and callbacks.

Part 2: Getting to Know the Stream API

What is the Java Stream API?

The Java Stream API is a feature introduced in Java 8 that allows you to process collections of data in a functional and declarative style.

Instead of writing loops to iterate over data, you can use streams to filter, transform, group, or aggregate data with clean and expressive code.

✅ Filter - Keep only the elements that match a condition

Goal: Select items that meet a criterion (like an if condition in a loop)

List<String> names = List.of("Alice", "Bob", "Charlie");

names.stream()
     .filter(name -> name.startsWith("A"))
     .forEach(System.out::println);

📤 Output:

Alice

✅ Transform (Map) convert elements into something else:

Goal: Apply a transformation to each element (like modifying values in a loop)

List<String> words = List.of("java", "stream", "lambda");

words.stream()
     .map(String::toUpperCase)
     .forEach(System.out::println);

📤 Output:

JAVA  
STREAM  
LAMBDA

✅ 3. Group — organize elements by a shared property

 List<String> names = List.of("Maria", "Juan", "Abigail", "Pedro", "Amalia", "Pamela", "Ana");
 Map<Character, List<String>> initialCharacterToNames =
        names.stream().collect(Collectors.groupingBy(name -> name.charAt(0)));

 System.out.println(initialCharacterToNames);

📤 Output:

{P=[Pedro, Pamela], A=[Abigail, Amalia, Ana], J=[Juan], M=[Maria]}

✅ 4. Aggregate (Reduce) — combine elements into a single result

Goal: Collapse a stream into one value (e.g. sum, min, max, join)

List<Integer> numbers = List.of(1, 2, 3, 4, 5);

int sum = numbers.stream()
                 .reduce(0, Integer::sum);

System.out.println(sum);

📤 Output:

15

🔧 Part 3: Reviewing the Java Stream Pipeline (Simplified)

Now that we've seen how streams can be used to filter, transform, group, and aggregate data, you might be wondering:

How do all these operations fit together behind the scenes?

That's where the Stream pipeline comes in. A stream pipeline is a sequence of steps through which data flows. Each step performs an operation, like filtering, transforming, or collecting.

Think of it like an assembly line: data goes in → gets processed step by step → a result comes out.

This pipeline facilitates performing various steps with the data and finalizing with a result.

✅ A Stream Pipeline Has 3 Parts:

PartDescriptionExample
SourceWhere the data comes from (e.g. List, Set, Array)List.of("a", "b", "c")
Intermediate OperationsSteps that transform the data (return a Stream).filter(...), .map(...)
Terminal OperationEnds the pipeline and returns a result.collect(...), .forEach(...)

🎯 Example:

List<String> names = List.of("Alice", "Bob", "Charlie");

names.stream()                              // ✅ Source
     .filter(name -> name.length() > 3)     // 🔁 Intermediate
     .map(String::toUpperCase)              // 🔁 Intermediate
     .forEach(System.out::println);         // 🏁 Terminal

📤 Output:

ALICE  
CHARLIE

✅ Conclusion

As you've seen, lambdas and the Stream API introduce a powerful way to write cleaner, more expressive, and more maintainable Java code. These features are a gateway to functional programming in Java — a style that leads to fewer bugs, more modular logic, and better performance in many cases.

Here are 3 solid reasons to start using them in your everyday coding:

  • ✅ Cleaner, more maintainable code than traditional loops

  • ✅ Encourage immutability — especially helpful in multi-threaded applications.

  • ✅ Built-in support for parallel processing with .parallelStream(): – opening the door to faster execution with minimal effort.

Whether you're just beginning with modern Java or looking to sharpen your understanding, mastering lambdas and streams is a must.

📌 Stay tuned for the next part of this series, where we'll continue exploring Modern Java Features — one feature at a time.

More from this blog

Code Like a Woman

40 posts

Code, learnings, and experiences from a Latina in tech.