I am relatively new to Java, and often find that I need to sort a Map<Key, Value>
on the values.
Since the values are not unique, I find myself converting the keySet
into an array
, and sorting that array through array sort with a custom comparator that sorts on the value associated with the key.
Is there an easier way?
The commons-collections library contains a solution called TreeBidiMap. Or, you could have a look at the Google Collections API. It has TreeMultimap which you could use.
And if you don't want to use these framework... they come with source code.
While I agree that the constant need to sort a map is probably a smell, I think the following code is the easiest way to do it without using a different data structure.
}
And here is an embarrassingly incomplete unit test:
}
The result is a sorted list of Map.Entry objects, from which you can obtain the keys and values.
With Java 8, you can use the streams api to do it in a significantly less verbose way:
Sorting the keys requires the Comparator to look up each value for each comparison. A more scalable solution would use the entrySet directly, since then the value would be immediately available for each comparison (although I haven't backed this up by numbers).
Here's a generic version of such a thing:
There are ways to lessen memory rotation for the above solution. The first ArrayList created could for instance be re-used as a return value; this would require suppression of some generics warnings, but it might be worth it for re-usable library code. Also, the Comparator does not have to be re-allocated at every invocation.
Here's a more efficient albeit less appealing version:
Finally, if you need to continously access the sorted information (rather than just sorting it once in a while), you can use an additional multi map. Let me know if you need more details...
I've looked at the given answers, but a lot of them are more complicated than needed or remove map elements when several keys have same value.
Here is a solution that I think fits better:
Note that the map is sorted from the highest value to the lowest.
Based on @devinmoore code, a map sorting methods using generics and supporting both ascending and descending ordering.