← Back to Advanced Java Course | Chapter 3: Functional Programming | Lesson 6 of 6

Java Collectors

Collectors gather the results of a stream into a list, a map or a summary, like putting sorted items into containers at the end of a conveyor belt. They can group, split, and join too.
Syntax
java
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?

java
// 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);
	}
}

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

java
// 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);
	}
}

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

java
// 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);
	}
}

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

java
// 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);
	}
}

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

java
// 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());
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Using Collectors.toMap when two elements produce the same key, which throws an IllegalStateException; pass a merge function as the third argument.
  2. Having a null value in Collectors.toMap, which throws a NullPointerException.
  3. Expecting groupingBy to keep insertion order, when it returns a HashMap by default; pass a LinkedHashMap or TreeMap supplier if order matters.
Chapter Summary
  • 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.
  • Optional handles values that may be absent, and Collectors gather stream results.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.