Search code examples
javasortinghashmapsimpledateformattreemap

Sort a map with "MMMyyyy" as key


I have a map whose keys are in MMMyyyy format and i need to sort based on month. input:

unsorted: {
 "Dec2010": 1,
 "Apr2010": 1,
 "Feb2010": 0,
 "Nov2010": 2,
 "Mar2010": 0,
 "Jun2010": 2,
 "Sep2010": 1,
 "May2010": 0,
 "Oct2010": 1,
 "Jul2010": 0,
 "Aug2010": 0,
 "Jan2010": 1
}

After sorting it should be like below:

sorted: {
 "Jan2010": 1
 "Feb2010": 0,
 "Mar2010": 0,
 "Apr2010": 1,
 "May2010": 0,
 "Jun2010": 2,
 "Jul2010": 0,
 "Aug2010": 0,
 "Sep2010": 1,
 "Oct2010": 1,
 "Nov2010": 2,
 "Dec2010": 1,     
}

Currently i am using treemap which sorts it in alphabetical order but how do i get it sorted based on month hierarchy.

Code:

    Map<String, Integer> unsorted = new HashMap<>();
    unsorted.put("Dec2010", 1);
    unsorted.put("Apr2010", 1);
    unsorted.put("Feb2010", 0);
    unsorted.put("Nov2010", 2);
    unsorted.put("Mar2010", 0);
    unsorted.put("Jun2010", 2);
    unsorted.put("Sep2010", 1);
    unsorted.put("May2010", 0);
    unsorted.put("Oct2010", 1);
    unsorted.put("Jul2010", 0);
    unsorted.put("Aug2010", 0);
    unsorted.put("Jan2010", 1);

    System.out.println("\nSorted......");
    Map<String, Integer> sorted = new TreeMap<>(unsorted);
    for (Map.Entry<String, Integer> entry : sorted.entrySet()) {
        System.out.println("Key : " + entry.getKey()
                + " Value : " + entry.getValue());
    }

Solution

  • Let's try with a custom comparator:

    public class Main {
    
        public static void main(String[] args) {
    
            final SimpleDateFormat df = new SimpleDateFormat("MMMyyyy");
    
            Map<String, Integer> map = new TreeMap<>(new Comparator() {
                @Override
                public int compare(Object o1, Object o2) {
                    String s1 = (String) o1;
                    String s2 = (String) o2;
                    try {
                        return df.parse(s1).compareTo(df.parse(s2));
                    } catch (ParseException e) {
                        throw new RuntimeException("Bad date format");
                    }
                };
            });
    
            map.put("Dec2011",1);
            map.put("Jan2011",0);
            map.put("Feb2011",1);
            map.put("Mar2011",0);
            map.put("Oct2011",1);
            map.put("Sep2011",0);
    
            for(Map.Entry<String, Integer> entry : map.entrySet()) {
                System.out.println(entry.getKey() + " -> " + entry.getValue());
            }
    
        }
    }
    

    Output:

    Jan2011 -> 0
    Feb2011 -> 1
    Mar2011 -> 0
    Sep2011 -> 0
    Oct2011 -> 1
    Dec2011 -> 1