Java Collectors
In this page:
stream.collect(Collectors.toList());
stream.collect(Collectors.toSet());
stream.collect(Collectors.groupingBy(item -> key));
stream.collect(Collectors.joining(", "));
What is a Collector?
A Collector is used as the terminal operation in a Stream pipeline, and its job is to accumulate the stream's elements into some final container, such as a List, a Set, or a Map, depending on which Collector you choose.
Example: What is a Collector?
// 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<String> names = Stream.of("Ana", "Bob", "Cy")
.collect(Collectors.toList());
// Print a line to the console
System.out.println(names);
}
}
Login to try C/C++/Java/PHP code in the editor
Collecting into Maps
You can accumulate stream elements directly into a Map using Collectors.toMap(), for which you must supply both a key-mapper function and a value-mapper function describing how to derive each map entry from a stream element.
Example: Collecting into Maps
// 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<String> names = List.of("Ana", "Bob", "Cy");
// Create a stream from the collection to process it step by step
Map<String, Integer> lengths = names.stream()
.collect(Collectors.toMap(name -> name, String::length));
// Print a line to the console
System.out.println(lengths);
}
}
Login to try C/C++/Java/PHP code in the editor
Grouping Data
You can group stream elements together by some shared attribute using the Collectors.groupingBy() collector, which returns a Map whose keys are the grouping categories and whose values are lists of the elements in each group.
Example: Grouping Data
// 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<String> words = List.of("apple", "banana", "avocado", "blueberry");
// Create a stream from the collection to process it step by step
Map<Character, List<String>> grouped = words.stream()
.collect(Collectors.groupingBy(w -> w.charAt(0)));
// Print a line to the console
System.out.println(grouped);
}
}
Login to try C/C++/Java/PHP code in the editor
Partitioning Data
Partitioning is a special case of grouping where the grouping key is always a boolean, splitting the data into exactly two buckets. Use Collectors.partitioningBy() with a predicate to divide stream elements into a true list and a false list in a single pass.
Example: Partitioning Data
// 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
Map<Boolean, List<Integer>> partitioned = nums.stream()
.collect(Collectors.partitioningBy(n -> n % 2 == 0));
// Print a line to the console
System.out.println(partitioned);
}
}
Login to try C/C++/Java/PHP code in the editor
Joining and Summarizing
You can join string elements into one delimited string using Collectors.joining(), optionally supplying a delimiter, prefix, and suffix. To compute running statistics like counts, sums, or averages instead, use a Collectors.summarizingInt()-style collector.
Example: Joining and Summarizing
// 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<String> names = List.of("Ana", "Bob", "Cy");
// Create a stream from the collection to process it step by step
String joined = names.stream().collect(Collectors.joining(", ", "[", "]"));
// Create a stream from the collection to process it step by step
IntSummaryStatistics stats = names.stream()
.collect(Collectors.summarizingInt(String::length));
// Print a line to the console
System.out.println(joined + " avg=" + stats.getAverage());
}
}
Login to try C/C++/Java/PHP code in the editor
- Using
Collectors.toMapwhen two elements produce the same key, which throws anIllegalStateException; pass a merge function as the third argument. - Having a null value in
Collectors.toMap, which throws aNullPointerException. - Expecting
groupingByto keep insertion order, when it returns aHashMapby default; pass aLinkedHashMaporTreeMapsupplier if order matters.
- Lambda expressions and method references give a short way to write behavior.
- Functional interfaces and the Stream API process data with operations such as filtering and mapping.
Optionalhandles values that may be absent, andCollectorsgather stream results.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: