Java Stream API
In this page:
collection.stream()
.filter(item -> condition)
.map(item -> expression)
.collect(Collectors.toList());
What is a Stream?
A Stream represents a pipeline of computational steps applied to a sequence of elements. It lets you process a collection's data in a declarative, functional style, describing what transformation you want rather than writing an explicit loop, and it never modifies the underlying data source.
Example: What is a Stream?
import java.util.*;
public class Main {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3, 4, 5);
long count = nums.stream().count(); // declarative, no explicit loop
System.out.println(count);
}
}
Login to try C/C++/Java/PHP code in the editor
Filter and Map
The filter() operation selects only the elements that match a given condition, discarding the rest from the pipeline. The map() operation instead transforms every element in the stream into a new value, one-for-one, without changing how many elements are present.
Example: Filter and Map
// Import java.util.* so it can be used by its short name
import java.util.*;
// Import java.util.stream.* so it can be used by its short name
import java.util.stream.*;
// Define the class Main
public class Main {
// Program entry point: the JVM starts running here
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3, 4, 5, 6);
// Create a stream from the collection to process it step by step
List<Integer> result = nums.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.collect(Collectors.toList());
// Print a line to the console
System.out.println(result);
}
}
Login to try C/C++/Java/PHP code in the editor
Terminal Operations - Collect
Terminal operations are what actually trigger a stream pipeline to execute, since intermediate operations like filter() and map() are lazy and do nothing until a terminal operation is called. The collect() terminal operation gathers the pipeline's final results back into a concrete container, such as a List or Set.
Example: Terminal Operations - Collect
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<String> names = List.of("Riya", "Aman", "Zoya");
List<String> upper = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList()); // triggers the pipeline
System.out.println(upper);
}
}
Login to try C/C++/Java/PHP code in the editor
Reduction and Matching
You can combine every element in a stream down into a single value using reduce(), for example to sum a list of numbers or find a maximum. You can also check whether elements satisfy a condition using short-circuiting matchers like anyMatch(), allMatch(), or noneMatch(), which stop scanning as soon as the answer is determined.
Example: Reduction and Matching
// Import java.util.* so it can be used by its short name
import java.util.*;
// Define the class Main
public class Main {
// Program entry point: the JVM starts running here
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3, 4, 5);
// Create a stream from the collection to process it step by step
int sum = nums.stream().reduce(0, Integer::sum);
// Create a stream from the collection to process it step by step
boolean anyEven = nums.stream().anyMatch(n -> n % 2 == 0);
// Print a line to the console
System.out.println(sum + " " + anyEven);
}
}
Login to try C/C++/Java/PHP code in the editor
Parallel Streams
You can execute a stream's operations in parallel across multiple CPU cores simply by calling parallelStream() instead of stream(). Make sure any operations you chain onto it are stateless and free of shared mutable state, since parallel execution can otherwise introduce hard-to-debug data races.
Example: Parallel Streams
// Import java.util.* so it can be used by its short name
import java.util.*;
// Define the class Main
public class Main {
// Program entry point: the JVM starts running here
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3, 4, 5);
int sum = nums.parallelStream()
.mapToInt(Integer::intValue)
.sum();
// Print a line to the console
System.out.println(sum);
}
}
Login to try C/C++/Java/PHP code in the editor
- Reusing a stream after a terminal operation like
count(), which throws anIllegalStateException; create a new stream instead. - Building a pipeline with only
filterandmapand no terminal operation, so nothing runs because intermediate operations are lazy. - Adding results to a shared
ArrayListfrom a parallel stream's lambda, which is not thread-safe; usecollectinstead.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: