Reputation: 11
I am new to java 8 and would like to write a function which sorts hashmap by values and if values are the same sort by keys.
To sort the hashmap by values:
Map<String, Integer> map1 = new LinkedHashMap<>();
map.entrySet()
.stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.forEachOrdered(x -> map1.put(x.getKey(), x.getValue()));
map1.forEach((k,v) ->{ System.out.println(k +" "+v);} );
I have worked with Python 3 and it has sorting for both keys and values using mapSorted = sorted(map.items()
, key = lambda item : (item[1], item[0]))
. Is there something similar in Java 8?
Upvotes: 1
Views: 2460
Reputation: 31918
The API you are looking forward to is Comparator#thenComparing
. The reason why the implementation for such sorting is not straightforward is because of the type-inference.
The type inference needs some help which can be provided such as :
Comparator.comparing(Map.Entry<String, Integer>::getValue)
.reversed().thenComparing(Map.Entry::getKey)
Apart from which you shall ideally collect the output to a Map that preserves the order, otherwise, the sorting is a waste of computations. Hence something like this shall work:
LinkedHashMap<String, Integer> sortedMap = map.entrySet()
.stream()
.sorted(Comparator.comparing(Map.Entry<String, Integer>::getValue)
.reversed().thenComparing(Map.Entry::getKey))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(a, b) -> a, LinkedHashMap::new));
Upvotes: 3
Reputation: 131
define your map
HashMap<String, Integer>map1 = new HashMap();
map1.put("aa",5);
map1.put("bbb",2);
map1.put("ccccc",2);
map1.put("dddddd",3);
sort,if you want to compare with string your need defining it by yourself
List<Entry<String, Integer>> collect = map1.entrySet().stream().sorted(new Comparator<Entry<String, Integer>>(){
@Override
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
int ll=0;
if (o1.getValue()>o2.getValue()){
ll=-1;
}
else if(o1.getValue()<o2.getValue()){
ll=1;
}
else if (o1.getKey().length()>o2.getKey().length()) {
ll=-1;
}
else if (o1.getKey().length()<o2.getKey().length()) {
ll=1;
};
return ll;
}
}).collect(Collectors.toList());
the result like [aa=5, dddddd=3, ccccc=2, bbb=2]
Upvotes: 0