collect
TL;DR
collect()is a terminal operation used to transform the elements of a stream into a different data structure (like aList,Set, orMap).- It is a mutable reduction operation.
- The
Collectorsutility class provides pre-built collectors for almost every common scenario (e.g.,Collectors.toList()).
Concept
While reduce() combines elements into a single immutable value (like an int), collect() gathers elements into a mutable container (like an ArrayList or a HashMap).
You will use collect() in almost every Stream pipeline you write, because streams themselves cannot be stored or reused. Once you have filtered and mapped your data, you must “collect” it back into a standard Java Collection to return it or pass it to other methods.
Examples
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class CollectExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Bob");
// 1. Collect to a List (Preserves order, allows duplicates)
List<String> list = names.stream()
.filter(n -> n.length() > 3)
.collect(Collectors.toList());
// In Java 16+, you can just use .toList()
// 2. Collect to a Set (Removes duplicates)
Set<String> set = names.stream()
.collect(Collectors.toSet());
System.out.println(set); // [Alice, Bob, Charlie]
// 3. Collect to a Map (Key, Value)
// Let's map Name -> Length.
// Note: This will throw an error if duplicate keys exist!
Map<String, Integer> map = set.stream() // using set to guarantee unique keys
.collect(Collectors.toMap(
name -> name, // Key mapper
name -> name.length() // Value mapper
));
System.out.println(map); // {Bob=3, Alice=5, Charlie=7}
// 4. Joining Strings
String joined = names.stream()
.collect(Collectors.joining(", "));
System.out.println(joined); // "Alice, Bob, Charlie, Bob"
}
}
Interview Questions
Q: How can you collect stream elements into a specific type of collection, like a LinkedList or TreeSet?
A: By default, Collectors.toList() returns an ArrayList and toSet() returns a HashSet. If you need a specific implementation, you use Collectors.toCollection(), which takes a Supplier for the collection you want.
Example: .collect(Collectors.toCollection(LinkedList::new));
Q: What happens in Collectors.toMap if there are duplicate keys?
A: If your stream contains elements that generate the exact same Key, Collectors.toMap will throw an IllegalStateException: Duplicate key. To fix this, you must provide a third argument to toMap(): a merge function that tells Java what to do when two values collide on the same key.
Example: .collect(Collectors.toMap(KeyMapper, ValueMapper, (value1, value2) -> value1)) (This keeps the first value and discards the duplicate).