Sort Employees by Salary
Java coding interview problem for Collections: Sort Employees by Salary.
Sorting objects is one of the most common problems in Java interviews.
Unlike sorting primitive values:
int[]
sorting custom objects requires understanding:
- Object comparison
- Comparable interface
- Comparator interface
- Lambda expressions
- Collections sorting
The Sort Employees by Salary problem teaches an important Java programming pattern:
Employee Objects
↓
Define Comparison Logic
↓
Apply Sorting Algorithm
↓
Sorted Employee List
What is Object Sorting?
Object sorting means arranging objects based on one or more attributes.
Example Employee:
Employee
id
name
department
salary
We can sort employees by:
- Salary
- Name
- Department
- Employee ID
- Joining Date
Example
Input Employees:
Employee(101, "John", 90000)
Employee(102, "Alice", 120000)
Employee(103, "Bob", 75000)
Sort by salary ascending:
Output:
Bob 75000
John 90000
Alice 120000
Sort by salary descending:
Output:
Alice 120000
John 90000
Bob 75000
Why Sorting Employees is Asked in Interviews?
This problem tests:
1. Object-Oriented Programming
Can you design:
Employee class
correctly?
2. Java Collections Knowledge
Understanding:
- List
- ArrayList
- Collections.sort()
3. Comparison Logic
Can you define:
Which employee comes first?
4. Java 8 Features
Modern solutions use:
- Lambda expressions
- Stream API
- Method references
Real-World Applications
Employee Management Systems
Companies sort employees by:
- Salary
- Performance score
- Experience
Payroll Systems
Examples:
Highest salary employees
Lowest salary employees
Banking Applications
Sort customers by:
- Account balance
- Transaction volume
E-Commerce Systems
Sort products by:
- Price
- Rating
- Popularity
Problem Statement
Given a list of employees, sort employees based on their salary.
Employee Model
Each employee contains:
id
name
salary
Employee Class
class Employee {
private int id;
private String name;
private double salary;
public Employee(
int id,
String name,
double salary) {
this.id = id;
this.name = name;
this.salary = salary;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
@Override
public String toString() {
return id + " "
+ name
+ " "
+ salary;
}
}
Input Example
Employees:
[
John 90000,
Alice 120000,
Bob 75000
]
Expected Output
Ascending salary:
Bob 75000
John 90000
Alice 120000
Understanding Object Comparison
When sorting integers:
Arrays.sort(numbers);
Java already knows:
1 < 2 < 3
For objects:
Java does not know:
Which employee is greater?
Example:
Employee A
salary = 90000
Employee B
salary = 120000
Who comes first?
We need to define the rule.
Comparable vs Comparator Overview
Java provides two ways:
Comparable
vs
Comparator
Comparable
Used when:
Class has natural ordering
Example:
Employee default sorting:
salary ascending
Implementation:
implements Comparable<Employee>
Comparator
Used when:
Multiple sorting strategies are required
Examples:
Sort by:
salary
name
department
without modifying Employee class.
Comparable Example Flow
Employee Class
|
|
implements Comparable
|
|
compareTo()
|
|
Collections.sort()
Comparator Example Flow
Employee List
|
|
Comparator Object
|
|
compare()
|
|
Collections.sort()
Sorting Algorithms Used Internally
Java uses optimized sorting algorithms.
For objects:
TimSort
is used.
TimSort combines:
Merge Sort
+
Insertion Sort
TimSort Characteristics
Time Complexity:
Best:
O(n)
Average:
O(n log n)
Worst:
O(n log n)
Space:
O(n)
Approach 1 — Manual Sorting Using Loops
Before Java Collections, developers used manual sorting.
Example:
Compare every employee
Swap positions
Repeat
Bubble Sort Logic
For every pair:
Compare:
Employee salary
If incorrect order:
Swap.
Example
Employees:
90000
75000
120000
Pass 1:
Compare:
90000 > 75000
Swap:
75000
90000
120000
Pass 2:
Already sorted.
Java Program — Manual Sorting
import java.util.ArrayList;
import java.util.List;
public class EmployeeBubbleSort {
public static void sort(
List<Employee> employees) {
int n =
employees.size();
for(int i = 0;
i < n - 1;
i++) {
for(int j = 0;
j < n - i - 1;
j++) {
if(employees.get(j)
.getSalary()
>
employees.get(j + 1)
.getSalary()) {
Employee temp =
employees.get(j);
employees.set(
j,
employees.get(j + 1));
employees.set(
j + 1,
temp);
}
}
}
}
}
Step-by-Step Explanation
Initial:
John 90000
Alice 120000
Bob 75000
Compare:
John vs Alice
No swap.
Compare:
Alice vs Bob
Swap.
Result:
John 90000
Bob 75000
Alice 120000
Next pass:
Compare:
John vs Bob
Swap.
Final:
Bob 75000
John 90000
Alice 120000
Complexity Analysis — Manual Sorting
Bubble Sort:
Time:
O(n²)
Space:
O(1)
Advantages
- Easy to understand.
- Good for learning sorting logic.
Drawbacks
- Poor performance.
- Reinvents existing Java functionality.
- Not used in production.
Approach 2 — Comparable Interface
The preferred object-oriented approach is:
Employee implements Comparable<Employee>
Comparable Structure
public class Employee
implements Comparable<Employee>
{
}
Implement:
compareTo()
method.
compareTo Logic
Return:
Negative:
Current object comes first
Zero:
Equal
Positive:
Current object comes after
Example:
return Double.compare(
this.salary,
other.salary
);
Approach 2 — Comparable Interface Sorting
The Comparable interface is used when a class has a natural ordering.
Example:
For Employee:
Default sorting:
Salary Ascending
The Employee class itself defines:
How employees should be compared
Implementing Comparable
Employee class:
class Employee
implements Comparable<Employee> {
private int id;
private String name;
private double salary;
public Employee(
int id,
String name,
double salary) {
this.id = id;
this.name = name;
this.salary = salary;
}
public double getSalary() {
return salary;
}
@Override
public int compareTo(
Employee employee) {
return Double.compare(
this.salary,
employee.salary);
}
@Override
public String toString() {
return name + " : "
+ salary;
}
}
Sorting Employees Using Comparable
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ComparableSorting {
public static void main(String[] args) {
List<Employee> employees =
new ArrayList<>();
employees.add(
new Employee(
101,
"John",
90000));
employees.add(
new Employee(
102,
"Alice",
120000));
employees.add(
new Employee(
103,
"Bob",
75000));
Collections.sort(employees);
System.out.println(
employees);
}
}
Output
Bob : 75000
John : 90000
Alice : 120000
Step-by-Step Execution
Before sorting:
John 90000
Alice 120000
Bob 75000
Comparison:
John vs Alice
Result:
90000 < 120000
John comes first.
Comparison:
Alice vs Bob
Result:
120000 > 75000
Bob moves before Alice.
Final:
Bob
John
Alice
Sorting Salary Descending Using Comparable
Change comparison:
return Double.compare(
employee.salary,
this.salary
);
Output:
Alice 120000
John 90000
Bob 75000
Approach 3 — Comparator Based Sorting
Comparator is preferred when:
- Multiple sorting rules exist.
- We cannot modify the class.
- Different views require different ordering.
Example:
Employee sorting options:
Salary
Name
Department
Experience
Comparator Structure
Employee List
|
Comparator
|
compare()
|
Sorted Result
Comparator Example — Salary Ascending
import java.util.Comparator;
public class SalaryComparator
implements Comparator<Employee> {
@Override
public int compare(
Employee e1,
Employee e2) {
return Double.compare(
e1.getSalary(),
e2.getSalary());
}
}
Sorting Using Comparator
Collections.sort(
employees,
new SalaryComparator()
);
Output
Bob 75000
John 90000
Alice 120000
Java 8 Lambda Comparator
Java 8 makes sorting much cleaner.
Salary Ascending
employees.sort(
(e1,e2) ->
Double.compare(
e1.getSalary(),
e2.getSalary()
)
);
Salary Descending
employees.sort(
(e1,e2) ->
Double.compare(
e2.getSalary(),
e1.getSalary()
)
);
Multiple Sorting Criteria
Real applications often require multiple rules.
Example:
1. Salary descending
2. Name ascending if salary is same
Example Data
John 90000
Alice 90000
Bob 75000
Expected:
Alice 90000
John 90000
Bob 75000
Comparator Chaining
employees.sort(
Comparator.comparing(
Employee::getSalary
)
.reversed()
.thenComparing(
Employee::getName
)
);
Sorting By Name
employees.sort(
Comparator.comparing(
Employee::getName
)
);
Output:
Alice
Bob
John
Sorting By Department
Employee:
name
salary
department
Comparator:
Comparator.comparing(
Employee::getDepartment
);
Stream API Sorting
Java Streams provide functional sorting.
Example
List<Employee> sortedEmployees =
employees.stream()
.sorted(
Comparator.comparing(
Employee::getSalary
)
)
.toList();
Descending Salary Stream
List<Employee> result =
employees.stream()
.sorted(
Comparator.comparing(
Employee::getSalary
)
.reversed()
)
.toList();
Method References
Instead of:
employee ->
employee.getSalary()
Use:
Employee::getSalary
Example:
Comparator.comparing(
Employee::getSalary
);
Benefits:
- Cleaner code.
- Better readability.
- Common Java 8 style.
Stable Sorting Concept
A stable sort maintains the original order of equal elements.
Example:
Before:
John 90000
Alice 90000
Bob 75000
Sort by salary:
Result:
John 90000
Alice 90000
Bob 75000
John stays before Alice.
Java object sorting:
TimSort
is stable.
Comparable vs Comparator
| Feature | Comparable | Comparator |
|---|---|---|
| Package | java.lang | java.util |
| Method | compareTo() | compare() |
| Location | Inside class | Separate class |
| Sorting Rules | Single | Multiple |
| Modifies Class | Yes | No |
| Best Use | Natural ordering | Custom ordering |
Primitive vs Object Sorting
Primitive Sorting
Example:
int[] numbers;
Uses:
Arrays.sort()
Complexity:
O(n log n)
Object Sorting
Example:
Employee[]
Uses:
Comparable
or
Comparator
Common Interview Mistakes
Mistake 1
Using subtraction for comparison.
Wrong:
return e1.salary - e2.salary;
Problem:
Overflow risk.
Correct:
Double.compare(
e1.salary,
e2.salary
);
Mistake 2
Forgetting null handling.
Example:
Employee salary = null
Use:
Comparator.nullsLast()
Mistake 3
Using Comparable for many sorting rules.
Better:
Comparator
Mistake 4
Changing original list accidentally.
Use:
stream().sorted()
when a new list is required.
Edge Cases
| Case | Handling |
|---|---|
| Empty employee list | Return empty |
| One employee | Already sorted |
| Same salary | Use secondary sorting |
| Null employees | Handle safely |
| Negative values | Use compare methods |
Interview Follow-up Questions
Q1. Sort employees by salary.
Q2. Sort employees by salary descending.
Q3. Sort by salary then name.
Q4. Difference between Comparable and Comparator.
Q5. How does Collections.sort() work internally?
Q6. Is Java sorting stable?
Q7. Sort objects using Streams.
Q8. Sort employees without modifying class.
Related Java Collection Problems
- Sort HashMap by Value
- Top K Frequent Elements
- Group Employees by Department
- Find Highest Salary Employee
- Remove Duplicate Objects
- Custom Object Sorting
Key Takeaways
Object sorting in Java follows:
Create Object
↓
Define Comparison Logic
↓
Apply Sorting
↓
Get Ordered Result
Recommended approach:
Single natural order:
Use:
Comparable
Multiple sorting requirements:
Use:
Comparator
Modern Java style:
employees.sort(
Comparator.comparing(
Employee::getSalary
)
);
Complexity:
Sorting Time:
O(n log n)
Frequently Asked Interview Questions
Q1. When should we use Comparable?
When a class has one natural ordering.
Q2. When should we use Comparator?
When different sorting strategies are required.
Q3. What sorting algorithm does Java use?
For objects:
TimSort
Q4. Why use Double.compare()?
To avoid overflow and handle floating values correctly.
Interview Tip
When asked:
"Sort Employees by Salary in Java."
Explain:
- Create Employee class.
- Decide sorting requirement.
- Use Comparable for natural ordering.
- Use Comparator for custom ordering.
- Use Java 8 lambda or method reference for clean implementation.
For senior Java interviews, discuss:
- Collections sorting internals.
- Stable sorting.
- Comparator chaining.
- Stream processing.
This demonstrates strong understanding of Java Collections, OOP design, and modern Java programming practices.