Sort Employees by Salary Using Streams in Java
Problem
Comparator.comparing builds a comparator from a key-extractor function, and thenComparing adds a tie-breaker used only when the first key is equal.
Given a list of employees, print them sorted by salary from highest to lowest, ordering employees with equal salaries alphabetically by name.
Java Program
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class SortEmployeesStream {
static class Employee {
private final String name;
private final String dept;
private final int salary;
Employee(String name, String dept, int salary) {
this.name = name;
this.dept = dept;
this.salary = salary;
}
String getName() { return name; }
String getDept() { return dept; }
int getSalary() { return salary; }
}
public static void main(String[] args) {
List<Employee> staff = Arrays.asList(
new Employee("Asha", "Engineering", 85000),
new Employee("Ravi", "Sales", 62000),
new Employee("Meera", "Engineering", 92000),
new Employee("John", "Sales", 62000),
new Employee("Liu", "HR", 58000));
staff.stream()
.sorted(Comparator.comparingInt(Employee::getSalary).reversed() // highest salary first
.thenComparing(Employee::getName)) // ties broken by name
.forEach(e -> System.out.println(e.getName() + " - " + e.getSalary()));
}
}Output
Core Logic
A comparator chain describes the ordering declaratively: primary key salary descending, secondary key name ascending.
- 1
Comparator.comparingInt(Employee::getSalary)compares employees by salary, lowest first. - 2
.reversed()flips that to highest first. - 3
.thenComparing(Employee::getName)is consulted only when two salaries are equal. - 4
sorted(...)applies the chain, andforEachprints each employee.
Key Point: Order matters in the chain: calling .reversed() after thenComparing would reverse the name order too, putting Ravi before John.
Why: The stream's sort is a comparison sort over n employees, and it buffers all elements to sort them.
Key Concepts
Approach 2: Sort by Department, Then Salary
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class SortEmployeesByDeptStream {
static class Employee {
private final String name;
private final String dept;
private final int salary;
Employee(String name, String dept, int salary) {
this.name = name;
this.dept = dept;
this.salary = salary;
}
String getName() { return name; }
String getDept() { return dept; }
int getSalary() { return salary; }
}
public static void main(String[] args) {
List<Employee> staff = Arrays.asList(
new Employee("Asha", "Engineering", 85000),
new Employee("Ravi", "Sales", 62000),
new Employee("Meera", "Engineering", 92000),
new Employee("John", "Sales", 62000),
new Employee("Liu", "HR", 58000));
staff.stream()
.sorted(Comparator.comparing(Employee::getDept) // A to Z by department
.thenComparing(Employee::getSalary, Comparator.reverseOrder())) // then richest first
.forEach(e -> System.out.println(e.getDept() + ": " + e.getName() + " - " + e.getSalary()));
}
}
Output
Core Logic
Swapping the keys gives a report-style ordering: departments alphabetically, and within each department the highest salary first.
- 1
Comparator.comparing(Employee::getDept)sorts departments A to Z. - 2
thenComparing(Employee::getSalary, Comparator.reverseOrder())reverses only the salary key. - 3Each line prints department, name and salary.
Key Point: Passing Comparator.reverseOrder() as the second argument reverses just that key — the safe way to mix ascending and descending fields.
Why: Same comparison sort, with a different comparator.
Key Concepts
Interview Questions
Does sorted() change the original list?
No. A stream never modifies its source; the sorted result exists only in the stream or the new collection it's collected into.
How do you get only the top three earners?
Add .limit(3) after sorted(...) in the pipeline.