I have a Map<String, Long> map
which I want to sort by the Long
value in reversed order using the features of Java 8. With Google I found this thread which provides this solution
Map<String, Long> sortedMap = map.entrySet().stream()
.sorted(comparing(Entry::getValue))
.collect(toMap(Entry::getKey, Entry::getValue,
(e1,e2) -> e1, LinkedHashMap::new));
If I want to have the order reversed in the comments it says to use comparing(Entry::getValue).reversed()
instead of comparing(Entry::getValue)
.
However, the code doesn't work. But with this little adaption it does:
Map<String, Long> sortedMap = map.entrySet().stream()
.sorted(Comparator.comparing(Entry::getValue))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue,
(e1, e2) -> e1, LinkedHashMap::new));
Do I have to do some imports first to be able to run the original code?
What still remains to get the reversed order, since
Map<String, Long> sortedMap = map.entrySet().stream()
.sorted(Comparator.comparing(Entry::getValue).reversed())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue,
(e1, e2) -> e1, LinkedHashMap::new));
gives my an error message:
The type Map.Entry does not define getValue(Object) that is applicable here
As explained in this answer, the type inference of Java 8 hit its limit when you chain method invocations like in Comparator.comparing(Entry::getValue).reversed()
.
In contrast, when using nested invocations like in Collections.reverseOrder(Comparator.comparing(Entry::getValue))
it will work.
Of course, you can use static
import
s:
Map<String, Long> sortedMap = map.entrySet().stream()
.sorted(reverseOrder(comparing(Entry::getValue)))
.collect(toMap(Entry::getKey, Entry::getValue,
(e1, e2) -> e1, LinkedHashMap::new));
but it should be noted that the compiler likes to provide misleading error messages when you forget an import static
statement (i.e. the method can’t be found) and combine it with lambda expressions or method references.
As a final note, there are also the existing comparator implementations Map.Entry.comparingByValue()
and Map.Entry.comparingByValue(Comparator)
which allow you to use
Map<String, Long> sortedMap = map.entrySet().stream()
.sorted(reverseOrder(comparingByValue()))
.collect(toMap(Entry::getKey, Entry::getValue,
(e1, e2) -> e1, LinkedHashMap::new));
or
Map<String, Long> sortedMap = map.entrySet().stream()
.sorted(comparingByValue(reverseOrder()))
.collect(toMap(Entry::getKey, Entry::getValue,
(e1, e2) -> e1, LinkedHashMap::new));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With