The Java Streams API provides a modern way to process collections of objects. It allows for complex data processing tasks to be expressed in a concise and readable manner. Streams are sequences of elements that support various operations to transform or consume the data.
These operations can be categorized into two types: intermediate and terminal operations.
Intermediate Operations
Intermediate operations return a new stream. They are used to transform or filter the elements of the original stream but do not trigger any processing. They are lazy, meaning that they are not executed until a terminal operation is invoked on the stream. Intermediate operations are always stateless or stateful.
Common Intermediate Operations
filter
: Selects elements based on a predicate.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> filteredNames = names.stream()
.filter(name -> name.startsWith("A"))
.collect(Collectors.toList());
// Output: ["Alice"]
map
: Transforms each element using a function.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<Integer> nameLengths = names.stream()
.map(String::length)
.collect(Collectors.toList());
// Output: [5, 3, 7]
flatMap
: Transforms each element into a stream and flattens the resulting streams into a single stream.
List<List<String>> listOfLists = Arrays.asList(Arrays.asList("Alice", "Bob"), Arrays.asList("Charlie"));
List<String> flatList = listOfLists.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
// Output: ["Alice", "Bob", "Charlie"]
distinct
: Removes duplicate elements.
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4);
List<Integer> distinctNumbers = numbers.stream()
.distinct()
.collect(Collectors.toList());
// Output: [1, 2, 3, 4]
sorted
: Sorts the elements.
List<String> names = Arrays.asList("Charlie", "Alice", "Bob");
List<String> sortedNames = names.stream()
.sorted()
.collect(Collectors.toList());
// Output: ["Alice", "Bob", "Charlie"]
peek
: Acts as each element of the stream.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> peekedNames = names.stream()
.peek(name -> System.out.println(name))
.collect(Collectors.toList());
// Output: Prints each name to the console and returns the original list
Terminal Operations
Terminal operations produce a result or a side-effect and trigger the processing of the stream. Once a terminal operation is invoked, the stream can no longer be used.
Common Terminal Operations
collect
: Converts the stream to a collection or another data structure.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> collectedNames = names.stream()
.collect(Collectors.toList());
// Output: ["Alice", "Bob", "Charlie"]
forEach
: Acts as each element.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
// Output: Prints each name to the console
reduce
: Aggregates elements to a single value using an associative accumulation function.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, Integer::sum);
// Output: 15
toArray
: Converts the stream to an array.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
String[] namesArray = names.stream()
.toArray(String[]::new);
// Output: ["Alice", "Bob", "Charlie"]
findFirst
: Returns the first element of the stream.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Optional<String> firstName = names.stream()
.findFirst();
// Output: Optional[Alice]
count
: Returns the number of elements in the stream.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
long count = names.stream()
.count();
// Output: 3
anyMatch
, allMatch
,
noneMatch
: Check if any, all, or none of the elements match a given predicate.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
boolean anyMatch = names.stream()
.anyMatch(name -> name.startsWith("A"));
// Output: true
Example Usage
Here is an example combining both intermediate and terminal operations:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Edward");
List<String> filteredSortedNames = names.stream()
.filter(name -> name.length() > 3)
.sorted()
.collect(Collectors.toList());
System.out.println(filteredSortedNames);
// Output: ["Alice", "Charlie", "David", "Edward"]
}
}
Read more
Explain the Collections in Java
Features of Java 9, 10, 11. What's New?
Java Memory Management: Understanding Stack and Heap
Explain the Stream API introduced in Java 8. How does it work?
Leave Comment