Consider a scenario where you have a dataset containing various salary values, and you need to find the Nth highest salary. This task might arise in applications ranging from financial systems to human resources, where understanding salary distributions is crucial.
For Data Manipulation and Processing, Java's Stream API has proven to be a powerful tool for simplifying complex operations on collections. In this article, we will learn to find nth highest salary using Stream API.
N'th Highest Salary Using Stream API
Approach: Java 8's Stream API streamlines finding the nth highest salary in a list. Its declarative and functional approach makes the solution elegant and efficient. We'll explore this technique in detail.
Step By Step Implementation
Step 1: Create a Map of Employees mapping to their respective salaries.
Employees | Salaries |
|---|---|
Abrar |
30,000 |
Chand |
80,000 |
Kalam |
70,000 |
Raheem |
25,000 |
Kiran |
63,000 |
Esa |
45,000 |
Step 2: Let's sort them in descending order by their salaries.
Employees | Salaries |
|---|---|
Chand |
80,000 |
Kalam |
70,000 |
Kiran |
63,000 |
Esa |
45,000 |
Abrar |
30,000 |
Raheem |
25,000 |
From the above table, we can easily get the nth highest salary from the top. For example, 2nd highest salary is holding by the 2nd row [70,000->Kalam]
Below, is the implementation of above problem solution in Java using Stream API and its relevant methods.
// Java Program for problem solution
// Using Stream API
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class nthHighestSalary {
public static void main(String[] args)
{
// Create a HashMap to store employee
// names and their corresponding salaries
Map<String, Integer> map = new HashMap<>();
map.put("Abrar", 30000);
map.put("Chand", 80000);
map.put("kalam", 70000);
map.put("Raheem", 25000);
map.put("Kiran", 63000);
map.put("Esa", 45000);
// Specify the desired value of n
int n = 2;
// Get the nth highest salary along
// with the corresponding employee name
Map.Entry<String, Integer> res
= getNthHighestSalary(map, n);
// Print the result
System.out.println(res.getValue() + " = [ "
+ res.getKey() + " ]");
}
public static Map.Entry<String, Integer>
getNthHighestSalary(
Map<String, Integer> employeeSalaries, int n)
{
return employeeSalaries.entrySet()
.stream() // Use Stream API to sort the entries
// by salary in descending order
.sorted(Collections.reverseOrder(
Map.Entry.comparingByValue()))
.collect(
Collectors.toList()) // Collect the sorted
// entries into a List
.get(n
- 1); // Get the nth element from the list
}
}
Output
70000 = [ kalam ]
But wait, what if there are employees with same salaries? Will this approach works?? And, answer is big No. Let us check it in the
Example Employees with Same Salaries
Employees | Salaries |
|---|---|
Abrar |
20,000 |
Chand |
35,000 |
Kalam |
45,000 |
Raheem |
35,000 |
Kiran |
50,000 |
Esa |
45,000 |
Now, let's sort them in descending order with respect their salaries.
Employees | Salaries |
|---|---|
Kiran |
50,000 |
Kalam |
45,000 |
Esa |
45,000 |
Chand |
35,000 |
Raheem |
35,000 |
Abrar |
20,000 |
Now, for suppose we want to get the third highest salary. If we use the first approach and code we will get [45,000] but the actual 3rd highest salary is [35,000].
Below code is the implementation of this approach by grouping them according to their respective salaries and appending the first approach to it.
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class nthHighestSalary {
public static void main(String[] args) {
// Create a HashMap to store employee names and their corresponding salaries
Map<String, Integer> map = new HashMap<>();
// Populate the HashMap with employee names and salaries
map.put("Abrar", 20000);
map.put("Chand", 35000);
map.put("Kalam", 45000);
map.put("Raheem", 35000);
map.put("Kiran", 50000);
map.put("Esa", 45000);
// Specify the desired value of n
int n = 3;
// Get the nth highest salary along with the corresponding employee names
Map.Entry<Integer, List<String>> res = getDynamicNthHighestSalary(map, n);
// Print the result
System.out.println(res);
}
// Method to find the nth highest salary dynamically
public static Map.Entry<Integer, List<String>> getDynamicNthHighestSalary(Map<String, Integer> employeeSalaries, int n) {
// Using Java Streams to process the map and find the nth highest salary
// 1. Group employee names by their corresponding salaries
return employeeSalaries.entrySet()
.stream()
.collect(Collectors.groupingBy(
Map.Entry::getValue, // Group by salary
Collectors.mapping(Map.Entry::getKey, Collectors.toList()) // Collect employee names as a list for each salary
))
.entrySet()
.stream()
// 2. Sort the map entries by salary in descending order
.sorted(Collections.reverseOrder(Map.Entry.comparingByKey()))
// 3. Collect the sorted map entries into a List
.collect(Collectors.toList())
// 4. Get the nth element from the list (n - 1 as list index starts from 0)
.get(n - 1);
}
}
Output
35000=[Raheem, Chand]
By following these steps, developers can harness the power of Java's Stream API to efficiently find the nth highest salary, making code concise, readable, and maintainable.