Definition
- max(comparing(joinDate)) returns
Optionalcontaining the employee with the most recent (latest) joining date. - LocalDate implements
Comparable, soComparator.comparing(Employee::getJoinDate)uses natural ordering (chronological). - Per-department:
groupingBy(dept, maxBy(comparing(joinDate)))finds the most recent joiner in each department. - Earliest joiner: use
mininstead ofmaxto find the oldest joining date.
Rajesh at the National Bank of India asks HR: 'Who is our newest hire?' HR scans the joining dates of all employees and picks the one with the latest date. That scan is what max(comparing(joinDate)) does.
Understanding the Concepts
What does this question ask?
The interviewer wants you to find the maximum value of a date field in a stream. This tests Stream.max, Comparator.comparing, and Optional handling.
How do you find the most recent joiner?
package com.bank.hr;
import java.time.LocalDate;
import java.util.*;
public class MostRecentJoiner {
public static void main(String[] args) {
List<Employee> employees = Employee.getSampleEmployees();
Optional<Employee> mostRecent = employees.stream()
.max(Comparator.comparing(Employee::getJoinDate));
mostRecent.ifPresent(e ->
System.out.println("Most recent: " + e.getName()
+ " joined " + e.getJoinDate()));
}
}
Most recent: Meera joined 2024-07-20
How do you find the earliest joiner?
Optional<Employee> earliest = employees.stream()
.min(Comparator.comparing(Employee::getJoinDate));
earliest.ifPresent(e ->
System.out.println("Earliest: " + e.getName()
+ " joined " + e.getJoinDate()));
Earliest: Suresh joined 2005-04-01
How do you find the most recent joiner per department?
Map<String, Optional<Employee>> recentPerDept = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.maxBy(Comparator.comparing(Employee::getJoinDate))));
recentPerDept.forEach((dept, opt) ->
opt.ifPresent(e ->
System.out.println(dept + ": " + e.getName()
+ " (" + e.getJoinDate() + ")")));
How do you handle null join dates?
// WRONG: NullPointerException if joinDate is null
Optional<Employee> wrong = employees.stream()
.max(Comparator.comparing(Employee::getJoinDate));
// CORRECT: filter nulls first
Optional<Employee> correct = employees.stream()
.filter(e -> e.getJoinDate() != null)
.max(Comparator.comparing(Employee::getJoinDate));
// CORRECT: use nullsFirst/nullsLast
Optional<Employee> withNulls = employees.stream()
.max(Comparator.comparing(Employee::getJoinDate,
Comparator.nullsFirst(Comparator.naturalOrder())));
What is the difference between max(comparing(date)) and sorted().findFirst()?
| Approach | Time complexity | Short-circuits? | Result |
|---|---|---|---|
| max(comparing(date)) | O(n) single pass | No | Optional
| sorted(date.reversed()).findFirst() | O(n log n) sort | Yes after first | Optional
max is O(n) because it scans once. sorted().findFirst() sorts the entire stream first, which is O(n log n). Use max for finding a single extreme value.
What are common mistakes?
Mistake: confusing max and min for dates.
// WRONG: min gives the EARLIEST date, not the most recent
Optional<Employee> wrong = employees.stream()
.min(Comparator.comparing(Employee::getJoinDate));
// This is Suresh (2005), not Meera (2024)!
// CORRECT: max gives the LATEST (most recent) date
Optional<Employee> correct = employees.stream()
.max(Comparator.comparing(Employee::getJoinDate));
What are common interview follow-up questions?
- "How do you find the 3 most recent joiners?" Use
sorted(comparing(joinDate).reversed()).limit(3). - "How do you find who joined in the same month as the most recent joiner?" First find the max date, then filter by its month.
- "What if two employees joined on the same day?"
maxreturns the first one in encounter order. UsethenComparing(name)for deterministic tie-breaking.
Visual Overview
Stream<Employee> (with join dates)
[2015-03, 2021-06, 2005-04, 2022-03, 2024-07, ...]
│
│ .max(comparing(getJoinDate))
▼
Scans all elements, tracks latest date:
2015-03 → current max = 2015-03
2021-06 → current max = 2021-06 (later)
2005-04 → current max = 2021-06 (earlier, skip)
2022-03 → current max = 2022-03 (later)
2024-07 → current max = 2024-07 (later)
│
▼
Optional[Meera, 2024-07-20] ← most recent
Key Takeaway
Finding the most recent joiner uses max(Comparator.comparing(Employee::getJoinDate)) because the latest date is the maximum in chronological order. LocalDate implements Comparable, so the natural ordering comparator works directly.
For per-department most recent, combine with groupingBy: groupingBy(dept, maxBy(comparing(joinDate))). For the earliest joiner, swap max for min.
The max approach is O(n), scanning once. The alternative sorted().findFirst() is O(n log n) because it sorts first. Always prefer max for a single extreme.
Remember one sentence: max with comparing(joinDate) finds the most recent joiner in O(n), and min finds the earliest.
---