How to sort a Map in Java
Published: August 9, 2010 , Updated: August 9, 2010 , Author: mkyong
A full Java example to demonstrate how to sort a Map (HashMap) based on its values. The overall idea is, convert the Map into List, sort the List and put the sorted list back to a Map.
Map ---> List ---> Sort ---> Map
Map sorting example
import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; public class SortMapExample{ public static void main(String[] args) { System.out.println("Unsort Map......"); Map<String,String> unsortMap = new HashMap<String,String>(); unsortMap.put("1", "1"); unsortMap.put("2", "A"); unsortMap.put("3", "2"); unsortMap.put("4", "B"); unsortMap.put("5", "C"); unsortMap.put("6", "c"); unsortMap.put("7", "b"); unsortMap.put("8", "a"); Iterator iterator=unsortMap.entrySet().iterator(); for (Map.Entry entry : unsortMap.entrySet()) { System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue()); } System.out.println("Sorted Map......"); Map<String,String> sortedMap = sortByComparator(unsortMap); for (Map.Entry entry : sortedMap.entrySet()) { System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue()); } } private static Map sortByComparator(Map unsortMap) { List list = new LinkedList(unsortMap.entrySet()); //sort list based on comparator Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { return ((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } }); //put sorted list into map again Map sortedMap = new LinkedHashMap(); for (Iterator it = list.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); sortedMap.put(entry.getKey(), entry.getValue()); } return sortedMap; } }
Result
Unsort Map...... Key : 3 Value : 2 Key : 2 Value : A Key : 1 Value : 1 Key : 7 Value : b Key : 6 Value : c Key : 5 Value : C Key : 4 Value : B Key : 8 Value : a Sorted Map...... Key : 1 Value : 1 Key : 3 Value : 2 Key : 2 Value : A Key : 4 Value : B Key : 5 Value : C Key : 8 Value : a Key : 7 Value : b Key : 6 Value : c







Thanks for the very nice piece of code :)
Very nice website thanks for ur work..
[...] ??????http://www.mkyong.com/java/how-to-sort-a-map-in-java/ Categories: Java, Programming Comments (0) Trackbacks (0) Leave a comment Trackback [...]
Nice man,
Mine, very quick attempt without much thinking, after having a few beers:) :
sortedValues = new TreeSet(unsortMap.values()).asList();
HashMap sortedMap = new HashMap
for (Object value : sortedValues) { //sorted iteration
for ( Set entry : unsortMap.entrySet() {
if (entry.getValue().equals(value) {
sortedMap.put(entry.getKey(), entry.getValue());
}
}
}
[...] | http://www.mkyong.com [...]
There’s no guarantee the posted implementation will work. Or work on every platform.
The contract for a Map does not guarantee the ordering of its Map.Entry members.
So, just because you sort the values and then put them back in the map in that order, there’s no contract guarantee that the collection returned from values() or an iteration of the entrySet() will be in that order.
The replies that use TreeMap with a special comparator might work, but they defy the contract of TreeMap, which says the entries are sorted by KEY; wrap that TreeMap in a new class that makes an explicit contract to order its entries by value and hide all the implementation details inside.
Thanks for your sharing, So, do you have alternative way to sort a Map by ts value?
why does one need to do this, I wonder… then I may have a solution…
LinkedHashMap is a concrete class? I’ve never needed to do what is being described, so… ignorance is bliss… I stick to using Map as an interface and do not write code that requires a specific implementation.
Isn’t that what the LinkedHashMap does? Provide a predictable iteration order based on input order?
Take it to the next level and make it like TreeMap but on the values so whenever you insert it goes into the sorted by value spot.
Here is a shorter version I’ve written that doesn’t use a list
Thanks for this non-list sorting example, but this put the map’s value sorted in descending order, can it be ascending as well?
Yes inverse k1 and k2 in the comparator
Still more shorter :) try this..
TreeMap sortedByValues = new TreeMap(unsortedMap);
sortedMap – map will be sorted by key.
Few comments:
1) The example is probably better named ValueSortedMap, to not confusing with existing java.util.SortedMap, which is by keys.
2) Your example mixed with Java generics and then not using it all the way through. Very annoying. You should correctly typing the List and Map.Entry for example will save you from casting.
3) Probably good to mention a great use case for this is where you use a Map model to display a HTML form (spring form) option list, and want to sort the listing values.
4) If you are not going to have duplicated values in the map, consider using the commons-collections library, which provided TreeBidiMap just for this. You just call inverseBidiMap() to get a reversed map with values sorted as keys! But the library is not fitted with 1.5 generics though, minor thing consider you get all the implementation for free. :)
Really appreciated sharing your invaluable experience.