Lambda Expressions & Streams

Let’s jump into one of the most exciting and modern parts of Java β€” introduced in Java 8 β€” that really transforms how you write clean, expressive, and functional-style code:


⚑ Lambda Expressions & Streams in Java


🧠 What Are Lambda Expressions?

Lambda expressions are a shorthand way to represent an anonymous function β€” a block of code that can be passed around and executed later.

βœ… Before Java 8:

To pass behavior, you had to create an anonymous class:

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

βœ… With Lambda (Java 8+):

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

βœ… Why Use Lambdas?

BenefitDescription
Concise CodeLess boilerplate than anonymous classes
Functional StyleMakes code easier to read and reason about
Used in Streams, CollectionsEnables powerful operations like filter, map, reduce
Foundation of functional interfacesUsed in APIs like Comparator, Runnable, Predicate

πŸ”§ Syntax

(parameters) -> { body }

Examples:

// No parameters
() -> System.out.println("Hi")

// One parameter
name -> System.out.println("Hello " + name)

// Multiple parameters
(a, b) -> a + b

🎯 Functional Interface

A functional interface is an interface with only one abstract method.
It can have multiple default or static methods.

Examples from Java:

  • Runnable
  • Callable
  • Comparator<T>
  • Predicate<T>
  • Function<T, R>
  • Consumer<T>

You can use the @FunctionalInterface annotation to enforce this.

@FunctionalInterface
interface MyFunction {
    void apply();
}

πŸ“¦ Lambda Example with Functional Interface

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

public class LambdaDemo {
    public static void main(String[] args) {
        Greeting g = (name) -> System.out.println("Hello " + name);
        g.sayHello("Alice");
    }
}

🌊 Java Streams API


πŸ” What Are Streams?

Streams are a new way to process data in a functional style.
You can perform complex data processing like filtering, mapping, sorting, and reducing with clean, readable code.

βœ… Key Characteristics:

  • Declarative (What to do, not how)
  • Chainable
  • Lazy (operations run only when needed)
  • Don’t modify the original collection

πŸ“¦ Stream Pipeline

Collection -> Stream -> Intermediate Ops -> Terminal Op

πŸ›  Common Stream Operations

πŸ”Ή Intermediate Operations

OperationDescription
filterKeep elements matching a condition
mapTransform each element
sortedSort stream
distinctRemove duplicates
limitTake only N items

πŸ”Ή Terminal Operations

OperationDescription
forEachIterate over elements
collectConvert to List, Set, Map
countCount elements
reduceCombine into single result

πŸ”§ Stream Example

import java.util.*;

public class StreamExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Alex", "Brian");

        names.stream()
             .filter(name -> name.startsWith("A"))
             .map(String::toUpperCase)
             .sorted()
             .forEach(System.out::println);  // Output: ALEX, ALICE
    }
}

🧠 Real-World Use-Cases

TaskTraditional JavaStream API
Filter recordsLoops and ifsfilter()
Transform objectsManual mappingmap()
Aggregate valuesLoop and manual totalreduce() or collect()
Count, max, minManual comparisoncount(), max()

πŸ”₯ Stream + Collectors

List<String> names = Arrays.asList("Sam", "Samantha", "Sara");

List<String> result = names.stream()
    .filter(name -> name.startsWith("S"))
    .collect(Collectors.toList());

🧠 Summary: Lambda vs Stream

FeatureLambdaStream
ConceptAnonymous functionSequence of data operations
GoalDefine behaviorProcess data in a declarative way
Common UsageFunctional InterfacesCollections, Maps, Arrays

🏠 Homework for Students

1. Functional Interface & Lambda

  • Create an interface MathOperation with a method int operate(int a, int b)
  • Implement add, subtract, multiply as lambda expressions

2. Streams Practice

Given a list of names:

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

Use Stream API to:

  • Filter names starting with J
  • Convert to uppercase
  • Sort alphabetically
  • Collect into a new List<String>

3. Use reduce() to calculate the sum of a list of integers.


4. Bonus: Create a method that returns the longest string from a list using Streams.


Would you like to continue into Method References and Optional, or dive into Collections Framework deep-dive, or go toward File I/O, Threads, or JDBC next?