Java Streams API

The Java Streams API (introduced in Java 8) provides a modern, functional-style way to process collections of data. It allows you to work with sequences of elements (like List, Set, or arrays) using declarative operations such as filtering, mapping, reducing, collecting, and more, while supporting parallel execution.


Key Concepts

  • Stream: A sequence of elements supporting sequential and parallel operations.
  • Intermediate operations: Transform a stream into another stream (lazy operations). Examples: filter(), map(), sorted().
  • Terminal operations: Produce a result or a side-effect and end the stream pipeline. Examples: collect(), forEach(), reduce().

Examples

1. Creating Streams

import java.util.*;
import java.util.stream.*;

public class StreamExamples {
    public static void main(String[] args) {
        // From a list
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

        Stream<String> stream1 = names.stream();
        
        // From an array
        String[] arr = {"one", "two", "three"};
        Stream<String> stream2 = Arrays.stream(arr);

        // Using Stream.of
        Stream<Integer> stream3 = Stream.of(1, 2, 3, 4, 5);

        // Infinite stream (example: odd numbers)
        Stream<Integer> oddNumbers = Stream.iterate(1, n -> n + 2);
    }
}

In Java, Streams (introduced in Java 8) provide a powerful way to work with collections and data processing using functional programming concepts. You can think of Stream functions as operating at different “levels” — from creation, through intermediate transformations, to terminal operations.

Here’s a breakdown of Stream functions by level 👇


🧩 1. Stream Creation (Source Level)

These functions create a stream from data sources like collections, arrays, or generators.

Source TypeExampleDescription
Collectionlist.stream()Creates a stream from a Collection (List, Set, etc.)
ArraysArrays.stream(arr)Converts an array into a stream
Static FactoryStream.of(1, 2, 3)Creates a stream from given values
Infinite StreamStream.iterate(0, n -> n + 2)Creates an infinite sequential stream
Random Streamnew Random().ints()Stream of random ints, longs, doubles
File StreamFiles.lines(Path)Reads lines from a file as a Stream

⚙️ 2. Intermediate Operations (Transformation Level)

These return another stream, allowing chaining.
They are lazy — they don’t process data until a terminal operation is invoked.

FunctionDescriptionExample
filter(Predicate)Filters elementsstream.filter(x -> x > 10)
map(Function)Transforms each elementstream.map(String::toUpperCase)
flatMap(Function)Flattens nested streamsstream.flatMap(List::stream)
distinct()Removes duplicatesstream.distinct()
sorted()Sorts elementsstream.sorted()
sorted(Comparator)Custom sortingstream.sorted(Comparator.reverseOrder())
peek(Consumer)Performs an action for each element (for debugging/logging)stream.peek(System.out::println)
limit(long n)Truncates the streamstream.limit(5)
skip(long n)Skips first n elementsstream.skip(3)

🎯 3. Terminal Operations (Execution Level)

These trigger the stream processing and produce a result (value, collection, or side effect).

FunctionDescriptionExample
forEach(Consumer)Iterates over elementsstream.forEach(System.out::println)
collect(Collector)Gathers elements into a collection or summary resultstream.collect(Collectors.toList())
toArray()Converts to arraystream.toArray()
reduce(...)Reduces to a single value (sum, min, etc.)stream.reduce(0, Integer::sum)
count()Counts elementsstream.count()
findFirst()Returns the first element (Optional)stream.findFirst()
findAny()Returns any element (Optional)stream.findAny()
anyMatch(Predicate)Returns true if any element matchesstream.anyMatch(x -> x > 10)
allMatch(Predicate)Returns true if all elements matchstream.allMatch(x -> x > 0)
noneMatch(Predicate)Returns true if no element matchesstream.noneMatch(x -> x < 0)
min(Comparator)Finds minimumstream.min(Integer::compare)
max(Comparator)Finds maximumstream.max(Integer::compare)

🌊 Stream Processing Flow (Summary)

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

int result = numbers.stream()        // 1️⃣ Stream Creation
    .filter(n -> n % 2 == 0)         // 2️⃣ Intermediate (filter)
    .map(n -> n * n)                 // 2️⃣ Intermediate (map)
    .reduce(0, Integer::sum);        // 3️⃣ Terminal (reduce)

System.out.println(result); // Output: 56 (4 + 16 + 36)

🧠 Bonus: Parallel Streams

You can process streams in parallel for performance on multicore CPUs:

list.parallelStream()
    .filter(...)
    .map(...)
    .collect(Collectors.toList());

Leave a Reply