Java 8 Features (Lambda Expressions & Streams)
Java 8 was a major turning point in the Java ecosystem. Before Java 8, Java was powerful but often very verbose. Java 8 introduced features that made Java more expressive, cleaner, and closer to real-world problem solving.
In this lesson, we focus on the two most important Java 8 features: Lambda Expressions and Streams.
Why Java 8 Was Needed
As applications grew larger, developers needed a simpler way to work with collections, write less boilerplate code, and express logic clearly.
Java 8 addressed this by:
- Reducing repetitive code
- Improving readability
- Making Java more functional
- Handling data collections efficiently
What Are Lambda Expressions?
A Lambda expression is a short block of code that represents a function.
Instead of writing a full method, we can write logic inline in a much simpler way.
Think of a Lambda as: "What to do" instead of "How to structure it".
Traditional Code vs Lambda
Before Java 8, using an interface looked like this:
Runnable task = new Runnable() {
public void run() {
System.out.println("Task running");
}
};
With Lambda expressions:
Runnable task = () -> System.out.println("Task running");
Same behavior, much cleaner code.
Where Lambdas Are Used
- Sorting collections
- Filtering data
- Event handling
- Multithreading
Anytime you pass behavior as an argument, Lambdas are useful.
Functional Interfaces
A Lambda works only with functional interfaces.
A functional interface has:
- Exactly one abstract method
Example:
@FunctionalInterface
interface Calculator {
int add(int a, int b);
}
Using Lambda with Collections
Let’s take a real-world list example:
List numbers = Arrays.asList(10, 20, 30, 40);
numbers.forEach(n -> System.out.println(n));
This prints each number using a Lambda.
What Are Streams?
Streams allow you to process data in a declarative way.
Instead of manually looping through collections, you describe what you want to do.
Streams do not store data — they operate on existing collections.
Stream Example
Filtering even numbers:
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
This reads like plain English: filter even numbers and print them.
Common Stream Operations
- filter() – select elements
- map() – transform elements
- sorted() – sort data
- forEach() – process each element
- collect() – gather results
Real-World Example
Imagine a list of employee salaries. We want salaries above 50,000.
List salaries = Arrays.asList(30000, 45000, 60000, 80000);
salaries.stream()
.filter(s -> s > 50000)
.forEach(System.out::println);
This is clean, readable, and efficient.
Advantages of Streams
- Less code
- Better readability
- Easy parallel processing
- Improved performance for large datasets
Important Notes
- Streams do not modify original data
- They execute only when a terminal operation is used
- Lambdas improve clarity, not just brevity
Industry Usage
Java 8 features are heavily used in:
- Enterprise applications
- Spring and Spring Boot
- Microservices
- Backend APIs
Modern Java development is impossible without Java 8 features.
Key Takeaways
- Lambdas reduce boilerplate code
- Streams simplify data processing
- Java becomes more expressive and readable
In the next lesson, we will build a Modern Java Project to apply everything you have learned.