Back to Stream Practice: Employee Analysis
Q27Question 27 of 43

Find the department with the most diverse age range (max - min age)

Key Concepts
  • groupingBy(dept, summarizingInt(age)) gives IntSummaryStatistics per department including min and max
  • Age range = stats.getMax() - stats.getMin() per department
  • entrySet().stream().max(comparing(range)) finds the department with the widest range
  • Alternatively use teeing(minBy(age), maxBy(age), merger) per department for direct min/max
  • A department with one employee has range 0
  • This combines groupingBy, summarizingInt, and the aggregate-then-max pattern

Definition

Group by department with summarizingInt(age), compute max - min for each department's statistics, then find the department with the largest range.
  • groupingBy(dept, summarizingInt(age)) gives Map with min, max, count, sum, avg per department.
  • Range = stats.getMax() - stats.getMin() per department.
  • max(comparing(range)) on the entrySet finds the most diverse department.
  • Single-employee departments have range 0.

The bank's diversity team asks: 'Which department has the widest age gap between youngest and oldest?' Compute the min and max age per department, subtract, and pick the largest difference.

Understanding the Concepts

How do you find the department with the widest age range?

JAVA
package com.bank.hr;

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

public class MostDiverseAgeRange {
    public static void main(String[] args) {
        List<Employee> employees = Employee.getSampleEmployees();

        Map<String, IntSummaryStatistics> statsByDept = employees.stream()
            .collect(Collectors.groupingBy(
                Employee::getDepartment,
                Collectors.summarizingInt(Employee::getAge)));

        Optional<Map.Entry<String, IntSummaryStatistics>> widest =
            statsByDept.entrySet().stream()
                .max(Comparator.comparingInt(
                    e -> e.getValue().getMax() - e.getValue().getMin()));

        widest.ifPresent(e -> {
            IntSummaryStatistics s = e.getValue();
            System.out.printf("%s: range = %d (min=%d, max=%d)%n",
                e.getKey(),
                s.getMax() - s.getMin(),
                s.getMin(), s.getMax());
        });
    }
}
TEXT
RISK: range = 27 (min=28, max=55)

What are common mistakes?

Mistake: computing max and min with separate streams instead of summarizingInt.

JAVA
// Inefficient: two passes per department
// Use summarizingInt for both min and max in one pass

What about the teeing approach for min and max?

Java 12+ teeing can collect min and max in one pass without summarizingInt:

JAVA
Map<String, int[]> ranges = employees.stream()
    .collect(Collectors.groupingBy(
        Employee::getDepartment,
        Collectors.teeing(
            Collectors.minBy(Comparator.comparingInt(Employee::getAge)),
            Collectors.maxBy(Comparator.comparingInt(Employee::getAge)),
            (min, max) -> new int[]{
                min.map(Employee::getAge).orElse(0),
                max.map(Employee::getAge).orElse(0)})));

What about excluding departments with fewer than 3 employees?

JAVA
statsByDept.entrySet().stream()
    .filter(e -> e.getValue().getCount() >= 3)
    .max(Comparator.comparingInt(
        e -> e.getValue().getMax() - e.getValue().getMin()))
    .ifPresent(e -> System.out.println(e.getKey()));

What about finding the department with the smallest range?

Replace max with min in the comparator.

What about the summarizingDouble alternative?

Instead of summarizingInt for ages, use summarizingDouble for salary ranges.

JAVA
import java.util.DoubleSummaryStatistics;

Map<String, DoubleSummaryStatistics> salaryStats = employees.stream()
    .collect(Collectors.groupingBy(
        Employee::getDepartment,
        Collectors.summarizingDouble(e -> e.getSalary().doubleValue())));

What about finding the average age range across departments?

JAVA
double avgRange = statsByDept.values().stream()
    .mapToInt(s -> s.getMax() - s.getMin())
    .average().orElse(0);

System.out.println("Average age range: " + avgRange);

What are the edge cases?

A department with one employee has range 0. A department with two employees has range equal to the absolute difference between their ages.

What are common interview follow-up questions?

  • "How do you find the department with the smallest range?" Replace max with min.
  • "How do you exclude departments with fewer than 3 employees?" Filter stats by count >= 3.

Visual Overview

DIAGRAM
  groupingBy(dept, summarizingInt(age))
  ┌──────────────────────────────────────────────┐
  │  TRADING     → min=28, max=45  range=17      │
  │  RISK        → min=28, max=55  range=27 ← max│
  │  OPERATIONS  → min=32, max=58  range=26      │
  │  COMPLIANCE  → min=29, max=52  range=23      │
  └──────────────────────────────────────────────┘

Key Takeaway

Finding the most diverse age range per department uses summarizingInt(age) as the downstream to get min and max in one pass, then computes max - min for each department and finds the largest range.

Remember one sentence: summarizingInt gives min, max, and more in one pass, and max - min gives the age range per department.

---

Share
Use ← → arrow keys to navigate