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 🤫