Course contents

Collectors: interview questions & scenarios

Premium12 questions · 18 what-if follow-ups

These are the collector questions I use to check whether you can design the result shape, not just remember Collectors.toList(). Answer it out loud first, then open the model answer, and revisit the lessons when a detail feels fuzzy: Collectors deep dive, groupingBy and partitioningBy in depth, Collectors.toMap and working with maps, Collecting to immutable collections and Writing a custom collector.

Question 1. ConceptCoreAsked very often

What are the moving parts of a Collector, and why does the combiner matter?

Tests supplier, accumulator, combiner, finisher, characteristics

Show answerHide answer2 follow-ups

Model answer

A collector is a recipe for turning many stream elements into one result. The five pieces are supplier, accumulator, combiner, finisher and characteristics.

The supplier creates a fresh mutable accumulation container. The accumulator folds one element into that container. The combiner merges two partial containers, which is what parallel streams need. The finisher converts the work container into the published result, unless the collector has IDENTITY_FINISH.

Collector<String, StringJoiner, String> csv = Collector.of(
        () -> new StringJoiner(","),
        StringJoiner::add,
        StringJoiner::merge,
        StringJoiner::toString
);

The combiner matters because a sequential stream might never expose a bad one. A collector with a wrong combiner can pass local tests and then drop data, duplicate data or reorder data when somebody changes stream() to parallelStream().

How I’d say it in the interview

"A collector is mutable work hidden behind a clean terminal operation. Supplier makes the box, accumulator puts one item in, combiner merges boxes, finisher publishes the answer. I pay extra attention to the combiner because parallel execution depends on it."

Signals depth

Calling out that the supplier must create a fresh container, not reuse a shared list or map.

Red flags

Saying the combiner is optional, or saying IDENTITY_FINISH is fine when the finisher wraps, copies or converts the result.

Follow-ups interviewers ask next

  1. What if the stream is always sequential?

    I still write a correct combiner or I do not write a custom collector. Future code changes, library reuse and tests with parallelStream() should not turn the collector into a trap.

  2. What if the final result should be immutable?

    Use a mutable accumulator internally, then copy or wrap in the finisher. Do not claim IDENTITY_FINISH if that finisher does real work.

Question 2. What does it print?CoreAsked very often

What does this toMap code print, and where does it fail?

Tests duplicate keys, merge function, IllegalStateException

Show answerHide answer2 follow-ups

Model answer

import java.util.*;
import java.util.stream.*;

public class Main {
    record User(String id, String name) { }

    public static void main(String[] args) {
        List<User> users = List.of(
                new User("u1", "Mina"),
                new User("u2", "Ravi"),
                new User("u1", "Mira")
        );

        System.out.println(users.stream().collect(
                Collectors.toMap(User::id, User::name, (oldName, newName) -> oldName)
        ));

        users.stream().collect(Collectors.toMap(User::id, User::name));
    }
}

The first collection succeeds because it gives a duplicate-key policy: keep the old value. A typical Java 21 output is:

{u1=Mina, u2=Ravi}
Exception in thread "main" java.lang.IllegalStateException: Duplicate key u1 (attempted merging values Mina and Mira)

Do not rely on the HashMap print order as the point of the question. The important part is that the two-argument toMap overload treats duplicate keys as a bug and throws IllegalStateException.

How I’d say it in the interview

"The first collector keeps Mina for u1, then the second collector throws because u1 appears twice. Two-argument toMap is a uniqueness assertion, not a grouping operation."

Signals depth

Saying the merge function receives the mapped values, not the original User objects unless the value mapper returns the user.

Red flags

Adding (a, b) -> b without explaining why losing the first value is correct.

Follow-ups interviewers ask next

  1. What if I want all users per id?

    Use groupingBy(User::id) or groupingBy(User::id, mapping(...)). A one-key-to-many-values result is a bucket problem, not a toMap collision to hide.

  2. What if the API needs stable key order?

    Use the four-argument overload with a supplier such as LinkedHashMap::new for encounter order or TreeMap::new for sorted keys.

Question 3. What does it print?CoreCommonly asked

What happens when the toMap value mapper returns null?

Tests null values, toMap NPE, custom collect

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 4. What does it print?CoreAsked very often

Compare stream().toList() and collect(Collectors.toList()) in Java 21.

Tests mutability, null handling, contract versus implementation

Model answer, how to say it, 2 follow-ups: unlock with the Java Pass

Question 5. CodingCoreAsked very often

Write a multi-level groupingBy that counts orders by status and month.

Tests nested groupingBy, downstream counting, result types

Model answer, how to say it, 2 follow-ups: unlock with the Java Pass

Question 6. CodingCoreAsked very often

Given employees, return the top earner per department.

Tests groupingBy, maxBy, collectingAndThen, Optional unwrapping

Model answer, how to say it, 2 follow-ups: unlock with the Java Pass

Question 7. DebuggingCoreCommonly asked

Why can groupingBy throw when the classifier returns null?

Tests null classifier, map keys, groupingBy contract

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 8. ConceptWarm-upCommonly asked

When would you use partitioningBy instead of groupingBy?

Tests boolean classifier, both buckets, downstream collector

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 9. DesignSeniorCommonly asked

Design a collector choice for an API that returns unique SKUs per customer in input order.

Tests groupingBy, mapping, LinkedHashSet, order contract

Model answer, how to say it, 2 follow-ups: unlock with the Java Pass

Question 10. DebuggingSeniorCommonly asked

What is wrong with this custom collector?

Tests supplier freshness, shared mutable state, parallel correctness

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 11. ScenarioSeniorSometimes asked

Should you use groupingByConcurrent for every parallel grouping?

Tests concurrent collectors, ordering, merge cost, measurement

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Question 12. DesignSeniorSometimes asked

How would you build a top-10 collector, and when would you avoid it?

Tests custom collector, bounded heap, sorting trade-off

Model answer, how to say it, 1 follow-up: unlock with the Java Pass

Premium question set

Keep reading with the Java Pass

The rest of this question set is part of Java One-Stop Interview Prep: in-depth explanations, diagrams, model answers and how to say them in the interview.

From ₹199 · one-time payment · No auto-renewal

Lessons in Collectors