Reputation: 135
I want to sort a map using Java 8 streams and return a list of its key.
Map signature is:
Map<Integer, Integer> ranks = new HashMap<Integer, Integer>();
and the data will be like [ 1=6, 5=13, 2=11 ]
There are two conditions on which I have to sort and return a list of keys.
If all the values of the keys are different, then sort and return a list based values in descending order, e.g.
input [1=6 , 5=13 , 2= 11 , 4 = 14 ]
result [4,5,2,1]
If two or more values of the key are having same rank, then return these similar in an ascending order, and the rest of the item is in descending order with respect to their values, e.g.
input [2=6 , 5=13 , 1= 11 , 3=13 ,9 = 22 ] result [9,3,5,1,2]
Below is the code snippet which is working fine for condition 1, but not for condition 2.
List<Integer> ranksList = ranks.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.map(Map.Entry::getKey)
.limit(k)
.collect(Collectors.toList());
Upvotes: 10
Views: 11187
Reputation: 86276
Declare the Comparator
using thenComparing
for chaining.
Comparator<Map.Entry<Integer, Integer>> entryComparator
= Map.Entry.<Integer, Integer>comparingByValue(Comparator.reverseOrder())
.thenComparing(Map.Entry.comparingByKey());
Map<Integer,Integer> ranks = Map.of(2, 6, 5, 13, 1, 11, 3, 13, 9, 22);
List<Integer> ranksList= ranks.entrySet().stream()
.sorted(entryComparator)
.map(Map.Entry::getKey).limit(47)
.collect(Collectors.toList());
System.out.println(ranksList);
Output is the desired:
[9, 3, 5, 1, 2]
The type specification <Integer, Integer>
of comparingByValue
is necessary for Java to infer the types for Map.Entry.comparingByKey()
.
Upvotes: 6
Reputation: 31878
You are looking for a custom Comparator
such as this:
.sorted((o1, o2) -> o2.getValue().compareTo(o1.getValue()) == 0 ?
o1.getKey().compareTo(o2.getKey()) : o2.getValue().compareTo(o1.getValue()))
Theoretically,
compare the values first in descending order o2.getValue().compareTo(o1.getValue())
and
if they are equal compare the keys in the ascending order o1.getKey().compareTo(o2.getKey())
.
Upvotes: 8