Find Nth Highest Salary Using Java Streams API | Java 8

deb.anand
2 min readMar 5, 2024

--

Photo by Ben Guerin on Unsplash

Let’s assume we have a list of employee in a map data structure where key is the employee name(String) and value is the salary(int)

Map<String,Integer> map = new HashMap<>();
map.put("deb",5500);
map.put("atulya",3200);
map.put("deepak",6300);
map.put("subhasis",7400);
map.put("pallavi",7700);
map.put("srinivas",9500);
map.put("sripati",9700);
map.put("basu",5700);

Problem:

Write a program using Java 8 to find out the second highest salary. Please make the code generic so that we can find Nth salary without doing much changes.

We want to fetch the second highest salary. Below implementation should work fine.

public static Map.Entry<String,Integer> getNthHighestSalary(int n, Map<String,Integer> map){
return map.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) // Sorted in the reverse order
.collect(Collectors.toList())
.get(n-1); // since the index begins from 0, we just did n-1
}

Output:

srinivas = 9500

We just sorted the Map.Entry by value and retrieved the second element when n=2. But think of a scenario with below data where the solution fails with returning the random order.

Map<String,Integer> map = new HashMap<>();
Map<String,Integer> map = new HashMap<>();
map.put("deb",9700);
map.put("atulya",3200);
map.put("deepak",6300);
map.put("subhasis",9500);
map.put("pallavi",9500);
map.put("srinivas",9500);
map.put("sripati",9700);
map.put("basu",5700);

Actual output:

sripati=9700

Expected output:

9500=[subhasis, pallavi, srinivas]

The above solution fails as it should return all the employees list with the second highest salary.

Next we will do the group by value and get the groups in a random order below.

Map<Integer, List<String>> map1 = map.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toList())
));

Output:

{3200=[atulya], 5700=[basu], 9700=[deb, sripati], 9500=[subhasis, pallavi, srinivas], 6300=[deepak]}

Next we need to sort the map by key in descending order with the below approach and then get second highest salary.

Map.Entry<Integer, List<String>> resultSalaryList = map.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toList())
))
.entrySet()
.stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByKey()))
.collect(Collectors.toList())
.get(n-1); //we can pass n=2 for second highest salary

Output:

9500=[subhasis, pallavi, srinivas]

I hope you find these blog posts helpful!

👏Clap if you ❤️ this blog . Follow n Subscribe for my future blogs.

💬Comment below if you have any questions ❓ or suggestions 💡.

🤝Connect with me on X

🗒️You might also be interested in: MongoDB Cost-Optimization Secrets They Don’t Want You to Know 🤫

--

--