How to sort HashMap keys

58,417

Solution 1

HashMaps do not store the sorted order of keys by definition. You can however accomplish this by acquiring an array of the keys via: Object[] keys = map.keySet().toArray(); Then sorting the list with Arrays: Arrays.sort(keys); and finally iterating through each key and retrieving the value from the HashMap.

for(Object key : keys) { System.out.println(map.get(key)); }

The sorting step here will make the algorithm run in O(n lg n) rather than O(n) which would be possible using a sorting data structure.

This will sort the list lexicographically. Since it looks like your question uses the common US date format, this will sort the list by day, then month and finally year. This is not likely correct. You can either use a year, month, day string format of the date, or adopt a more appropriate key object. Joda-Time's DateTime and DateTimeComparator would be quite useful. Simply use DateTime as the key and a DateTimeComparator instance when calling Arrays.sort(keys, comparator);.

Solution 2

Keys of a map are stored in a Set which can not be sorted. You can do it by adding the keys of the map set into a List and sorting that instead.

e.g.

List<Date> sortedKeys = new ArrayList<Date>(dateMilestoneMap.size());
sortedKeys.addAll(dateMilestoneMap.keySet());
Collections.sort(sortedKeys); //sorts in ascending date order 
                             //(pass in custom Comparator to sort differently)..

Here I've used the Date class which is much better for storing dates than plain Strings.

Solution 3

HashMap doesn't define the order of iteration over the elements. If you want to retrieve elements sorted by key use the TreeMap instead. However, since you store the strings in the format "DD/MM/YYYY" the order will likely be not the one you want, so either use the Date as a key or at least string of the form like "YYYY-MM-DD".

Solution 4

HashMap doesn't provide any ordering when you iterate over it (or even guarantee that the order will stay the same if you loop multiple times). If you want a natural ordering over the keys, try TreeMap. Note that your strings are formatted dd/mm/yy, so when the TreeMap orders them it's going to be ascending by day first, not by year, which is probably not what you want. You should either use strings like yy/mm/dd, switch to using a class that encapsulates that information better like Date, or define your own Comparator when you construct the TreeMap that knows how to sort your dd/mm/yy strings in the right order

Share:
58,417
Naveen A
Author by

Naveen A

Updated on July 09, 2022

Comments

  • Naveen A
    Naveen A almost 2 years

    I have one problem

    HashMap<String, List<AppPrjMilestone>> dateMilestoneMap
                                     = new HashMap<String, List<AppPrjMilestone>>();
    

    I am putting dynamic key in Hashmap object like this:

    dateMilestoneMap.put(""+crateDate,value);
    

    Finally I am getting result like this:

    ("28/01/2012",value)
    ("01/01/2012",value)
    ("26/01/2012",value)
    

    I want return key value pairs in desc or asc order. How can I do that?

  • Brett
    Brett over 12 years
    Why not Collection.sort? And why not use a comparator on Map.Entry?
  • allingeek
    allingeek over 12 years
    Collections.sort(...) works but takes a List, which HashMap does not implement. You would have to convert it to something like an ArrayList via new ArrayList(map). In the end, its basically the same mechanism. If the keys are Strings, they will be sorted lexicographically.
  • user949300
    user949300 over 12 years
    -1 Also, I have to ding this answer because this still won't sort by date, because the String representation he uses for the date doesn't sort by date!
  • Brett
    Brett over 12 years
    @allingeek Ah yes, I was thinking List instead of Set for entrySet.
  • allingeek
    allingeek over 12 years
    I'm pretty sure the question was about sorting a keys of a HashMap.
  • allingeek
    allingeek over 12 years
    I've addressed the sorting order in my answer. @user949300 This should make you a bit happier. Although, I'm pretty sure your suggestion to sort Map.keySet() is exactly what I'm talking about. You cannot sort a Set, as it is also unordered.
  • Michael Mrozek
    Michael Mrozek over 12 years
    @allingeek I'm not. He was vague, but I think he wants to loop over the map and get the keys in ascending or descending order, so he should just use a map that provides that. If it's literally "I need to use a HashMap, but I want the keys in order anyway" he should probably specify that, but I think it's more "I'm using HashMap but it doesn't do what I want; how do I deal with it?"
  • Louis Wasserman
    Louis Wasserman over 12 years
    Making a TreeMap copy of the HashMap might actually be the best way to sort the keys.
  • j-a
    j-a about 6 years
    @allingeek the algorithm would run in O(n lg n) regardless if using a sorting data structure.
  • allingeek
    allingeek about 6 years
    @j-a Well, this was 6 years ago. But I'm guessing what I meant was that by using a sorted data structure you would only pay the sorting penalty when building the set. That would make sorted list enumeration linear vs paying the sorting penalty every time.
  • Elliptica
    Elliptica over 5 years
    You can actually do it a little more directly: List<Date> sortedKeys = new ArrayList<Date>(dateMilestoneMap.keyset()); Collections.sort(sortedKeys);