Java Programs›Java 8 Streams›Find Second Highest Salary Using Streams

Find Second Highest Salary Using Streams in Java

intermediate·  Java 8 Streams  ·  Streams

Problem

The second-highest salary is the largest salary level below the top one, so duplicate top salaries must count as a single level.

Given a list of employees, find the second-highest distinct salary and list everyone who earns it.

Input
salaries 85000, 92000, 92000, 78000, 85000
Output
85000 (Asha, Liu)

Java Program

Java
import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Optional; public class SecondHighestSalary { static class Employee { private final String name; private final int salary; Employee(String name, int salary) { this.name = name; this.salary = salary; } String getName() { return name; } int getSalary() { return salary; } } public static void main(String[] args) { List<Employee> staff = Arrays.asList( new Employee("Asha", 85000), new Employee("Ravi", 92000), new Employee("Meera", 92000), new Employee("John", 78000), new Employee("Liu", 85000)); Optional<Integer> second = staff.stream() .map(Employee::getSalary) .distinct() // 92000 appears twice but is one salary level .sorted(Comparator.reverseOrder()) // highest first .skip(1) // drop the highest .findFirst(); System.out.println("Second highest salary: " + second.orElse(0)); staff.stream() .filter(e -> e.getSalary() == second.orElse(-1)) .map(Employee::getName) .forEach(name -> System.out.println("Earned by: " + name)); } }

Output

Second highest salary: 85000 Earned by: Asha Earned by: Liu

Core Logic

Reducing the salaries to distinct values, sorting them from highest to lowest and skipping the first one leaves the second-highest at the front.

How It Works
  1. 1map(Employee::getSalary) keeps only the salary numbers.
  2. 2distinct() collapses the two 92000 salaries into one level.
  3. 3sorted(Comparator.reverseOrder()) orders them highest first, and skip(1) drops the top value.
  4. 4findFirst() returns an Optional, and a second stream lists the employees with that salary.
The distinct salaries in descending order are 92000, 85000 and 78000, so skipping one gives 85000, earned by Asha and Liu.
💡

Key Point: Without distinct(), skipping the first value would return 92000 again — the most common mistake in this interview question.

Complexity
Time Complexity: O(n log n)Space Complexity: O(n)

Why: Sorting the distinct salaries dominates, and the distinct set may hold up to n values.

Key Concepts

distinct()sorted(Comparator.reverseOrder())skip()findFirst()

Approach 2: Nth Highest Salary

Java
import java.util.Arrays; import java.util.List; public class SecondHighestSalaryNth { static int nthHighest(List<Integer> salaries, int n) { return salaries.stream() .distinct() .sorted((a, b) -> b - a) .skip(n - 1) // the nth highest sits after n - 1 larger values .findFirst() .orElseThrow(() -> new IllegalArgumentException("Fewer than " + n + " distinct salaries")); } public static void main(String[] args) { List<Integer> salaries = Arrays.asList(85000, 92000, 92000, 78000, 85000); for (int n = 1; n <= 3; n++) { System.out.println(n + " -> " + nthHighest(salaries, n)); } try { nthHighest(salaries, 4); } catch (IllegalArgumentException e) { System.out.println("4 -> " + e.getMessage()); } } }

Output

1 -> 92000 2 -> 85000 3 -> 78000 4 -> Fewer than 4 distinct salaries

Core Logic

Skipping n − 1 values instead of exactly one turns the same pipeline into a reusable nth-highest method.

How It Works
  1. 1skip(n - 1) discards the n − 1 higher salary levels.
  2. 2orElseThrow raises a clear error when there are fewer than n distinct salaries.
  3. 3The loop prints the 1st, 2nd and 3rd highest values.
With only three distinct salaries, asking for the 4th highest throws the IllegalArgumentException.
💡

Key Point: Failing loudly is better than returning 0, which could be mistaken for a real salary.

Complexity
Time Complexity: O(n log n)Space Complexity: O(n)

Why: The same distinct-sort-skip pipeline runs for each n.

Key Concepts

skip(n - 1)orElseThrow()generalisation

Interview Questions

How would you write this in SQL?

A common answer is SELECT MAX(salary) FROM employees WHERE salary < (SELECT MAX(salary) FROM employees), or using DENSE_RANK() for any nth value.

Can you solve it without sorting?

Yes — keep two variables for the highest and second-highest distinct values in one pass, which is O(n).

Learn the Concept

Related Programs