Java Stream API
In this page:
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.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3, 4, 5, 6);
List<Integer> result = nums.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.collect(Collectors.toList());
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.*;
public class Main {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3, 4, 5);
int sum = nums.stream().reduce(0, Integer::sum);
boolean anyEven = nums.stream().anyMatch(n -> n % 2 == 0);
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.*;
public class Main {
public static void main(String[] args) {
List<Integer> nums = List.of(1, 2, 3, 4, 5);
int sum = nums.parallelStream()
.mapToInt(Integer::intValue)
.sum();
System.out.println(sum);
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: