Clean • Professional
The Stream API is one of the most powerful features introduced in Java 8. It allows developers to process data in a clean, efficient, and functional way.
If lambda expressions made Java code concise, the Stream API makes data processing more elegant and readable.
The Stream API in Java is used to process collections of data (like List, Set, etc.) in a functional programming style.
In simple words: A stream is a sequence of elements that supports operations like filtering, mapping, sorting, and collecting data.
It helps you write less code and perform complex data operations easily without using traditional loops.
Basic Example of Stream API
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
Output:
2
4
here,
stream() → converts the collection into a streamfilter() → selects only even numbersforEach() → processes and prints each elementBefore Java 8, processing collections required:
for, while)Stream API simplifies this by:
A stream works in three main steps:
1. Source: The data source from where the stream is created.
Example: Collection like List, Set, etc.
2. Intermediate Operations: Used to transform or filter data. These operations are lazy and can be chained.
Examples: filter(), map(), sorted()
3. Terminal Operation: Produces the final result or output. Without this, the stream will not execute.
Examples: forEach(), collect(), count()
Stream Flow
Collection → stream() → filter/map/sorted → terminal → result
Simple flow: Data → Process → Result
👉 This flow shows how data moves step-by-step in the Stream API.
Stream API operations are mainly divided into two types:
These operations transform the stream and return another stream. They are lazy, meaning they do not execute until a terminal operation is called.
Common intermediate operations:
filter() → selects elements based on a conditionmap() → transforms each elementsorted() → sorts elements (natural or custom order)distinct() → removes duplicate elementslimit() → limits the number of elementsflatMap() → flattens nested structures into a single streamExample:
numbers.stream()
.filter(n -> n > 2)
.map(n -> n * 2);
👉 This example filters numbers greater than 2 and then multiplies them by 2.
Used to flatten nested structures.
List<List<Integer>> list = Arrays.asList(
Arrays.asList(1, 2),
Arrays.asList(3, 4)
);
list.stream()
.flatMap(l -> l.stream())
.forEach(System.out::println);
Output: 1 2 3 4
These operations produce the final result and trigger the execution of the stream.
Common terminal operations:
forEach() → iterates over elementscollect() → converts stream into a collectioncount() → counts elementsfindFirst() → gets the first elementreduce() → combines valuesExample:
List<Integer> result = numbers.stream()
.filter(n -> n > 2)
.collect(Collectors.toList());
👉 This example filters numbers greater than 2 and collects them into a list.
Here are some commonly used Stream API methods in Java with simple examples:
1. filter()
Used to select elements based on a condition.
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
👉 This example prints only even numbers from the list.
2. map()
Used to transform each element in the stream.
numbers.stream()
.map(n -> n * n)
.forEach(System.out::println);
👉 This example converts each number into its square.
3. sorted()
Used to sort elements in natural order.
numbers.stream()
.sorted()
.forEach(System.out::println);
👉 This example sorts the numbers in ascending order.
4. collect()
Used to convert stream into a collection like List.
List<Integer> list = numbers.stream()
.filter(n -> n > 2)
.collect(Collectors.toList());
👉 This example filters numbers greater than 2 and stores them in a list.
5. reduce()
Used to combine elements into a single result.
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
👉 This example calculates the sum of all numbers.
List<String> names = Arrays.asList("Ram", "Shyam", "Amit");
names.stream()
.filter(name -> name.startsWith("A"))
.forEach(System.out::println);
👉 This example filters and prints names that start with "A".
Stream API also supports parallel processing, which allows tasks to run on multiple threads.
numbers.parallelStream()
.forEach(System.out::println);
👉 This example processes elements in parallel instead of sequentially.
👉 Important Notes on Parallel Streams
Use Stream API when:
Avoid using Stream API when:
Stream API is widely used in real-world applications for efficient data handling:
The Stream API in Java is a powerful tool for handling data in a modern, clean, and efficient way.
It works perfectly with:
By using Stream API, you can write less code, improve readability, and process data more effectively in real-world Java applications.