Java Tutorial 0/145 lessons ~6 min read Lesson 124

    Group By Multiple Fields

    group by multiple fields practice a focused java stream api coding question: group by multiple fields. solve it first with a stream

    Course progress0%
    Focus
    22 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Practice a focused Java Stream API coding question: Group By Multiple Fields. Solve it first with a stream pipeline, then compare it with the imperative alternative.

    Purpose of this lesson

    Build interview-ready Stream API muscle memory. Difficulty: Hard - XP: 100 - Estimated time: 20 min - Tags: groupingBy, records, multiple-fields.

    Understanding the topic

    Problem statement: Group employees by department and role.

    Sample input: Ana=IT/DEV, Ben=IT/QA, Cy=IT/DEV
    Expected output: {IT-DEV=[Ana, Cy], IT-QA=[Ben]}

    Approach: Create a composite key from the fields and use groupingBy.

    Syntax reference

    Stream solution:

    java
    record DeptRole(String department, String role) {}
    Map<DeptRole, List<Employee>> groups = employees.stream()
    .collect(Collectors.groupingBy(e -> new DeptRole(e.department(), e.role())));

    Alternative solution:

    java
    Map<String, List<Employee>> groups = new HashMap<>();
    for (Employee e : employees) {
    String key = e.department() + "-" + e.role();
    groups.computeIfAbsent(key, k -> new ArrayList<>()).add(e);
    }

    Informative example

    Dry run: Ana and Cy share the IT/DEV key; Ben is placed under IT/QA.

    • Follow-up: Why is a record better than string concatenation?
    • Follow-up: How would you count each group instead of listing employees?

    Complexity analysis

    • Time: O(n)
    • Space: O(n)

    Real-world use

    Interactive challenge: complete the starter code, then compare with the reference solution.

    java
    static Object solve(List<?> input) {
    // TODO: write the Stream pipeline
    return null;
    }

    Reference solution:

    java
    record DeptRole(String department, String role) {}
    Map<DeptRole, List<Employee>> groups = employees.stream()
    .collect(Collectors.groupingBy(e -> new DeptRole(e.department(), e.role())));

    Hints:
    - Start with the operation that changes the number of elements.
    - Use a terminal operation that returns exactly the expected output type.
    - Write an empty-list test before the happy path.

    Best practices

    • Name the terminal operation and explain why it ends the pipeline.
    • Mention how nulls, empty inputs, duplicates, and ordering affect the answer.
    • State when a loop is clearer than a Stream pipeline.

    Common mistakes

    • Calling get() on an empty Optional instead of handling absence.
    • Using sorted() for a problem that only needs one pass.
    • Mutating external state inside map, filter, or forEach.

    Debugging tips

    • Print the intermediate result after each pipeline stage when the output surprises you.
    • Temporarily replace method references with lambdas so you can inspect parameter names and values.

    Optimization strategies

    • Avoid unnecessary distinct(), sorted(), and boxing on hot paths.
    • Use primitive streams such as mapToInt when aggregating large numeric collections.

    Advanced interview questions

    Interview Prep

    Practice concise answers, then expand each card for the explanation.

    2 questions
    1QuestionWhy is a record better than string concatenation?+

    Answer

    Explain the Stream operation choices, edge cases, ordering guarantees, and when an imperative loop would be clearer.
    2QuestionHow would you count each group instead of listing employees?+

    Answer

    Explain the Stream operation choices, edge cases, ordering guarantees, and when an imperative loop would be clearer.

    Hands-on exercise

    Practice progress metadata: difficulty=Hard, xp=100, estimatedTime=20 min, tags=groupingBy, records, multiple-fields.

    Summary

    You solved Group By Multiple Fields with Streams, compared it against an imperative alternative, reviewed complexity, and captured interview follow-ups.

    Purpose of this lesson

    Practice Stream API interview questions with production-style trade-offs, not just syntax recall.

    Step-by-step explanation

    1. State the input, output, and edge cases before writing the pipeline.
    2. Choose the smallest useful Stream operation: filter, map, flatMap, reduce, or collect.
    3. Compare the Stream answer with the imperative alternative and explain readability trade-offs.
    4. Check performance notes: stateful operations, boxing, sorting, distinct, and parallel overhead.

    Interactive workflow diagram

    1Group By Multiple Fields — typical flow
    1 / 4

    Identify use case

    Recognize when group by multiple fields is the right tool for the problem.

    Debugging tips

    • Insert a temporary peek() only while debugging, then remove it before committing.
    • If the result is missing rows, inspect every predicate in filter() with a small sample input.
    • When collectors produce unexpected maps, print the classifier key for each element.
    • When NOT to use Streams: complex branching, heavy mutation, tiny hot loops, or code where a clear loop is easier to review.

    Optimization strategies

    • Why distinct() can be expensive: it keeps a set of seen values and depends on correct equals/hashCode.
    • When parallel streams hurt performance: small data, blocking I/O, shared mutable state, or expensive splitting.
    • Common mistakes with reduce(): non-neutral identity values and non-associative accumulators break parallel correctness.
    • Stream pipeline optimization: filter early, avoid intermediate collections, prefer primitive streams for numeric aggregation.

    Enterprise example

    Teams at Netflix, Uber and Goldman Sachs apply Group By Multiple Fields daily — usually wrapped behind Spring Boot services with observability hooks (Micrometer + OpenTelemetry).

    Interview questions & answers

    Q1What interview insight should you mention for this Stream problem?
    Explain the chosen operation, empty-input behavior, ordering guarantees, and why the complexity is acceptable.
    Q2What alternative approach should you compare against?
    Describe the equivalent loop or map/set based solution, then say which version is clearer for production maintenance.
    Q3What performance note matters most?
    Call out stateful operations such as sorted() and distinct(), plus the overhead of boxing and parallel execution.

    Summary

    Use this question to practice both coding and explanation: the strongest interview answers include edge cases, trade-offs, and when not to use Streams.

    Ready to mark this lesson complete?Track your journey across the entire course.